设计图像类的一些技巧

我们在做和图像有关的项目时,很多情况下我们会"量身定做"一个图像类。以下就是我在做项目中总结的一些经验。(注:以CImgWrapper为例)
1.图像的Width和Height使用的频率很高,我们应该提供接口让用户很容易获得它们,如:
  public:
    int getWidth() const;
    int getHeight() const;
2.在很多情况下,我们需要图像的微缩图(thumbnail),一般我们都是根据现有图像,构造一个微缩图对象。其实我们使用微缩图的主要目的是用来显示,大可不必构造一个微缩图对象。我们可以为图像类添加两个成员变量:
  private:
    int cur_width; //图像显示的尺寸?
    int cur_height;
然后提供接口获取和设置这两个变量:
  public:
    int getCurWidth() const;
    int getCurHeight() const;
    void setCurWidth(int nw);
    void setCurHeight(int nh);
在Window平台下,以下就是显示1/4微缩图的代码:
    CImgWrapper image; //load image for file
    image.setCurWidth( image.getWidth()*0.25 );
    image.setCurHeight( image.getCurHeight()*0.25 );
    ::SetStretchBltMode(hdc, COLORONCOLOR);
    ::StretchDIBits(hdc,0,0,image.getCurWidth(),image.getCurHeight(),
                    0,0,image.getWidth(),image.getHeigh(),
                    lpBits,lpBitmapInfo,DIB_RGB_COLORS, SRCCOPY);
这样就可以显示1/4的微缩图。
3.一般的,图象文件应包含两部分的内容:用来描述图象文件本身,以头文件的形式存在;头文件后面的信息就是图象的象素信息,是图象文件的主要信息。我们设计的图象类也应包含这两部分的内容:
  private:
    char* pixelData;?? //指向象素信息的指针
    char* fileheaderData;? //指向头文件信息的指针
再完美的设计也不能考虑到所有的情况,所以需要提供一个获取原始象素信息的接口,通过这个接口,用户可以实现自定义的功能:
  public:
    char* getPixelData() { return pixelData; }
4.图象类的内存分配。一个图象文件可能会占据大量的内存。所以图象类之间的相互赋值,拷贝构造将会占据大量的内存和CPU时间,如:
    CImgWrapper a, b;
    //initalize a,b from files
    CImgWrapper c=a+b;
分析以上的代码:分别创建了a,b两个对象,a+b会生成一个临时对象用来表示a和b的和,通过此临时对象构造出c.在这个过程中,系统大部分时间用来了内存的分配和释放,效率变的很低。一般,高手们会采用引用记数的方法来减少内存的分配和释放,设计比较复杂。我是菜鸟,复杂的不会,所以只能使用一些简陋的办法,在一定的场合还是可以用的:
不允许对象之间赋值和拷贝构造,可以通过将拷贝构造函数和“=“操作符设为private:
  private:
    CImgWrapper& operator=( const CImgWrapper& rhs );
    CImgWrapper( const CImgWrapper& rhs );
提供一个拷贝函数完成对象与对象之间内存的深拷贝:
    CImgWrapper* Copy( const CImgWrapper* pRhs );
5.提供一个default constructor构建一个"null image":
    CImgWrapper() { pixelData=null; fileheaderData=null; cur_width=0; cur_Height=0; }
提供"null image"的必要性在于在某些操作中,可能操作失败,这样通过返回"null image"表示操作失败.
6.提供一个constructor,将图像文件装入内存中,同时和一个CImgWrapper对象关联:
    CImgWrapper( const?char* file );
7.提供一个装载图片的函数,将图片文件装入内存:
  public:
    void LoadImage( const char* file );
  与之相对应,提供一个卸载函数,释放图像对象占的内存,将图像对象设为"null image":
  public:
    void ReleaseImage();
以上就是我在做项目中获得的一些经验,随着项目的深入,会有更多的收获,同时可能会对现有的认识作出修改.

注:对于那些熟悉OOP,Design Pattern的资深程序员,推荐《Applied C++:Practical Techniques for Building Better SoftWare》这本书,这本书以建立一个图像类为例,阐述了大量构建优秀软件的技巧,大量运用了OOP,Design Pattern等思想。

你可能感兴趣的:(image,File,null,oop,Constructor,colors)