CxImage的使用

 

原文地址:http://www.codeproject.com/KB/graphics/cximage.aspx

 

1.简介及许可

CxImage 是一个免费的C++类,可以简单而快速的加载、保存、显示,转换BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式图像。CxImage是开源的,和zlib的许可协议一致,你可以在任何想使用的地方使用它。

2.移植性

该类和项目在多个编译器下进行过测试,从vc6.0至vs2008,borland c++3至6,部分的wxDev c++ 和MinGw。

所有库都提供了UNICODE和非UNICODE配置。

3.CxImage结构

 

一个CxImage对象基本是一个bitmap,另外增加一些成员变量保存有用的信息。

 

class CxImage

  {

  ...

  protected:

  void* pDib;            //contains the header, the palette, the pixels

  BITMAPINFOHEADER head; //standard header

  CXIMAGEINFO info;       //extended information

  BYTE* pSelection;        //selected region

  BYTE* pAlpha;           //alpha channel

  CxImage** pLayers;    //generic layers

  }

CxImage::head 是一个位图头,CxImage::pDib 是通常的位图。CxImage::info 是一个存储在不同格式之间的许多共享信息,在所有成员函数中使用。

typedef struct tagCxImageInfo {

    DWORD   dwEffWidth;       //DWORD aligned scan line width

    BYTE*   pImage;           //THE IMAGE BITS

    void*   pGhost;           //if this is a ghost, pGhost point to the body

    DWORD   dwType;           //original image format

    char    szLastError[256]; //debugging

    long    nProgress;        //monitor

    long    nEscape;          //escape

    long    nBkgndIndex;      //used for GIF, PNG, MNG

    RGBQUAD nBkgndColor;      //used for RGB transparency

    BYTE    nQuality;         //used for JPEG

    long    nFrame;           //used for TIF, GIF, MNG : actual frame

    long    nNumFrames;       //used for TIF, GIF, MNG : total number of

                              //frames

    DWORD   dwFrameDelay;     //used for GIF, MNG

    long    xDPI;             //horizontal resolution

    long    yDPI;             //vertical resolution

    RECT    rSelectionBox;    //bounding rectangle

    BYTE    nAlphaMax;        //max opacity (fade)

    bool    bAlphaPaletteEnabled;  //true if alpha values in the palette are

                              // enabled.

    bool    bEnabled;         //enables the painting functions

    long    xOffset;

    long    yOffset;

    DWORD   dwEncodeOption;   //for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,

                              // 4=pack,5=jpg

    RGBQUAD last_c;           //for GetNearestIndex optimization

    BYTE    last_c_index;

    bool    last_c_isvalid;

    long    nNumLayers;

    DWORD   dwFlags;

} CXIMAGEINFO;

 

CxImage对象还是多层的集合。每层的缓冲只在必要的时候才被分配。

CxImage::pDib是背景图,CxImage::pAlpha 是透明层,CxImage::pSelection 是选择层,用于创建图像处理的感兴趣的区域。在这三层外,你还可以定义,然后存储在CxImage::pLayers中。CxImage::ppFrames为动态图像(gif)保留.

4.支持的格式和选项:

整个库是非常大的,在主要的头文件ximcfg.h中你将找到一些开放或禁止一些特定的图形格式或特征的开关,每个JPG、PNG、TIFF库将使最终的应用程序增加大约100K的容量,cximage会影响50K的容量大小,所以你应当只支持和链接你的应用程序真正需要的格式。

 

5.如何使用cximage

工作区CxImagelib.dsw展示了建立一个应用程序所需要的库,在连接最终的应用程序之前你必须编译所有的库。在这个工作区中你将发现建立不同的库和应用程序的工程。

         CxImage: cximage.lib                 -static library

CxImageCrtDll: cximagecrt.dll    -DLL not using mfc

CxImageMfcDll: cximage.dll       -DLL using mfc

Demo: demo.exe                        -program linked with cximage.lib and C Libraries

DemoDll: demodll.exe                    -program linked with cximagecrt.dll

j2k,jasper,jbig,jpeg,png,tiff,zlib:    -static C Libraries

 

在你的项目中使用CxImage,必须作如下设置

在你的程序中添加#include ”ximage.h”

使用CxImage写一个图像处理的新函数也很容易,下面描述怎样添加CxImage::Jitter

函数:首先声明该函数bool Jitter(long radius=2),在文件ximage.h的CXIMAGE_SUPPORT_DSP的部分公有函数的任何区域,然后如下代码进行定义

 

bool CxImage::Jitter(long radius)

{

    // check if the image is valid, this should be always the first line in

    // the function

    if (!pDib) return false;

   

    // local variables

    long nx,ny;

   

    // temporary image to store the partial results of the algorithm

    CxImage tmp(*this,pSelection!=0,true,true);

   

    // limit the effects of the functions only in the smallest rectangle that

    // holds the selected region (defined with the Selection...() functions ),

    // this will speed up the loops.

    long xmin,xmax,ymin,ymax;

    if (pSelection){

        xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;

        ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;

    } else {

        xmin = ymin = 0;

        xmax = head.biWidth; ymax=head.biHeight;

    }

   

    // main loop : scan the image in vertical direction

    for(long y=ymin; y <ymax; y++){

   

        // monitor the progress of the loops

        info.nProgress = (long)(100*y/head.biHeight);

   

        // let the application a way to exit quickly

        if (info.nEscape) break;

   

        // main loop : scan the image in horizontal direction

        for(long x=xmin; x<xmax; x++){

   

        // if the feature is enabled, process only the pixels inside the

        // selected region

#if CXIMAGE_SUPPORT_SELECTION

            if (SelectionIsInside(x,y))

#endif //CXIMAGE_SUPPORT_SELECTION

            {

                // main algorithm

                nx=x+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));

                ny=y+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));

                if (!IsInside(nx,ny)) {

                    nx=x;

                    ny=y;

                }

 

                // save the result in the temporary image.

                // if you can, use PixelColor only for 24 bpp images,

                // and PixelIndex for 8, 4 and 1 bpp images : it's faster

                if (head.biClrUsed==0){

                    tmp.SetPixelColor(x,y,GetPixelColor(nx,ny));

                } else {

                    tmp.SetPixelIndex(x,y,GetPixelIndex(nx,ny));

                }

 

                // if the feature is enabled, process also the pixels

                // in the alpha layer

#if CXIMAGE_SUPPORT_ALPHA

                tmp.AlphaSet(x,y,AlphaGet(nx,ny));

#endif //CXIMAGE_SUPPORT_ALPHA

 

            }

        }

    }

 

    // save the result and exit

    Transfer(tmp);

    return true;

}

应用实例

格式转换

Code:

CxImage  image;

// bmp -> jpg

image.Load("image.bmp", CXIMAGE_FORMAT_BMP);

if (image.IsValid()){

    if(!image.IsGrayScale()) image.IncreaseBpp(24);

    image.SetJpegQuality(99);

    image.Save("image.jpg",CXIMAGE_FORMAT_JPG);

}

// png -> tif

image.Load("image.png", CXIMAGE_FORMAT_PNG);

if (image.IsValid()){

    image.Save("image.tif",CXIMAGE_FORMAT_TIF);

}

加载图像资源

 

Code:

//Load the resource IDR_PNG1 from the PNG resource type

CxImage* newImage = new CxImage();

newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),

                       "PNG"),CXIMAGE_FORMAT_PNG);

or

Code:

//Load the resource IDR_JPG1 from DLL

CxImage* newImage = new CxImage();

HINSTANCE hdll=LoadLibrary("imagelib.dll");

if (hdll){

    HRSRC hres=FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1),"JPG");

    newImage->LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);

    FreeLibrary(hdll);

}

 

or

 

Code:

//Load a bitmap resource;

HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),

                              MAKEINTRESOURCE(IDB_BITMAP1)));

CxImage *newImage = new CxImage();

newImage->CreateFromHBITMAP(bitmap);

 

 

解码内存中的图像

Code:

CxImage image((BYTE*)buffer,size,image_type);

or

Code:

CxMemFile memfile((BYTE*)buffer,size);

CxImage image(&memfile,image_type);

 

or

 

Code:

CxMemFile memfile((BYTE*)buffer,size);

CxImage* image = new CxImage();

image->Decode(&memfile,type);

 

编码内存中的图像

Code:

long size=0;

BYTE* buffer=0;

image.Encode(buffer,size,image_type);

...

free(buffer);

 

or

 

Code:

CxMemFile memfile;

memfile.Open();

image.Encode(&memfile,image_type);

BYTE* buffer = memfile.GetBuffer();

long size = memfile.Size();

...

free(buffer);

 

创建一个多页的TIFF

 

Code:

CxImage *pimage[3];

pimage[0]=&image1;

pimage[1]=&image2;

pimage[2]=&image3;

 

FILE* hFile;

hFile = fopen("multipage.tif","w+b");

 

CxImageTIF multiimage;

multiimage.Encode(hFile,pimage,3);

 

fclose(hFile);

or

 

Code:

FILE* hFile;

hFile = fopen("c:\\multi.tif","w+b");

 

CxImageTIF image;

image.Load("c:\\1.tif",CXIMAGE_FORMAT_TIF);

image.Encode(hFile,true);

image.Load("c:\\2.bmp",CXIMAGE_FORMAT_BMP);

image.Encode(hFile,true);

image.Load("c:\\3.png",CXIMAGE_FORMAT_PNG);

image.Encode(hFile);

 

fclose(hFile);

 

拷贝粘贴图像

Code:

//copy

HANDLE hDIB = image->CopyToHandle();

if (::OpenClipboard(AfxGetApp()->m_pMainWnd->GetSafeHwnd())) {

    if(::EmptyClipboard()) {

        if (::SetClipboardData(CF_DIB,hDIB) == NULL ) {

            AfxMessageBox( "Unable to set Clipboard data" );

}    }    }

CloseClipboard();

 

//paste

HANDLE hBitmap=NULL;

CxImage *newima = new CxImage();

if (OpenClipboard()) hBitmap=GetClipboardData(CF_DIB);

if (hBitmap) newima->CreateFromHANDLE(hBitmap);

CloseClipboard();

 

在picture框中显示图像文件

 

Code:

HBITMAP m_bitmap = NULL;

CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);

...

m_bitmap = image.MakeBitmap(m_picture.GetDC()->m_hDC);

m_picture.SetBitmap(m_bitmap);

...

if (m_bitmap) DeleteObject(m_bitmap);

 

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值