分享

CxImage功能强大的图形处理程序

 赵东华 2016-01-24

CxImage是免费开源的使用简单的图形处理程序,在这里演示了两个功能。

1 在对话框上加一按钮,其函数为将BMP位图转换成TIF和JPEG。

2 在对话框上加一按钮,抓屏为BMP位图,通过剪切板保存为JPG文件。

 

一 CxImage简单使用说明

     大部分内容来自网上,做了适当地改进。

CxImage是免费开源的C++图形软件,支持BMP、GIF、ICO、TGA、JPEG、PCX、PNG、TIFF、MNG、RAS等文件格式,能够实现图像的导入、保存、显示,以及几何变换、格式转换,也可实现内存图像数据的类型转换。

CxImage的主要函数有:Constructors  构造函数,Initialization  初始化,File 文件编解码,Generic 图像基本变化,DSP 图像处理操作,Painting 绘图操作,Multiple Images 多帧图像操作,Transparency 透明层操作,Palette 调色板操作,Pixels 像素操作,Region Selection 区域选择操作,Alpha Channel Alpha通道操作,Layers 图像层操作,Attributes 图像属性操作,Miscellaneous 杂项等。

CxImage使用


1. 下载CxImage的源代码
可以到作者 Davide Pizzolato 主页: http://www./,或者http://www./bitmap/CXImage.asphttp://www./KB/graphics/cximage.aspx下载CxImage的源代码和完整Demo。可能需要先注册一个 codeproject的免费账号 。

 

2. 编译CxImage。
解压源码包,在解压后的目录下有一个CxImageLib.dsw工作空间文件,使用VC++ 6.0 打开该工作空间文件:
① Project->Settings->C/C++,在Category下拉列表中选择Code Generation,将Use rum-time libary中选择MultiThread DLL.在 Category下拉列表中选择 Precompiled Headers中,选择第一项: Not using Precompiled headers.
② Build->Batch Build->勾选你要编译的版本库。默认情况下是每个库都有四个版本,分别是Debug、Release、Unicode Debug、Unicode Release.选择你想要的版本,比如只勾选Debug即可。
③ 执行全部编译,等待几分钟,生成几个lib。

 

3. 建立自己的测试工程
① 打开VC++6.0,新建基于对话框的程序TestImg。

3.1 在对话框上加一按钮,其函数为将BMP位图转换成TIF和JPEG。
void CTestImgDlg::OnButton1()
{
 CxImage image;
 if( !image.Load("image.bmp", CXIMAGE_FORMAT_BMP)) return ;
 if (image.IsValid())
 {
  image.Save("image.tif",CXIMAGE_FORMAT_TIF);
  
  if (!image.IsGrayScale()) image.IncreaseBpp( 24 );//颜色数
  image.SetJpegQuality( 80);// 图像的质量
  image.Save("image.jpg",CXIMAGE_FORMAT_JPG );
 }
 
}

3.2 在对话框上加一按钮,点击抓屏BMP位图,通过剪切板保存为JPG文件。

void CTestImgDlg::OnButton2()
{
 CDC *pDC = GetDC();  
 CDC memDC;  
 memDC.CreateCompatibleDC(pDC);  //pDC兼容DC
 
 CRect rect;
 GetClientRect(&rect);  //客户区大小
 
 CBitmap m_bmpCatch;
 m_bmpCatch.CreateCompatibleBitmap(pDC, rect.Width(),  rect.Height());  //pDC兼容bmp
 memDC.SelectObject(&m_bmpCatch);  //选bmp
 memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rect.left, rect.top, SRCCOPY); //pDC --> m_bmpCatch 
 
 /


    long size = 0;  
    BYTE *buf = NULL;  
    image.Encode(buf, size, CXIMAGE_FORMAT_JPG);  
    image.SetJpegQuality(100); 
 image.Save("scr.jpg", CXIMAGE_FORMAT_JPG);    
 
    free(buf);    
 ReleaseDC(pDC);  
 memDC.DeleteDC();  
}

② 在TestImgDlg.cpp文件顶部,加入以下代码:

#include "img_h/ximage.h"

//#pragma comment(lib,"lib/cximagecrtd.lib") //静态链接库时使用,还要对应的cximagecrtd.dll
#pragma comment(lib,"img_lib/cximage.lib")
#pragma comment(lib,"img_lib/Jpeg.lib")
#pragma comment(lib,"img_lib/png.lib ")
#pragma comment(lib,"img_lib/zlib.lib ")
#pragma comment(lib,"img_lib/tiff.lib ")
#pragma comment(lib,"img_lib/jasper.lib ")
//#pragma comment(lib,"img_lib/jbig.lib ")
#pragma comment(lib,"img_lib/libdcr.lib ")
#pragma comment(lib,"img_lib/mng.lib ")

③ 根据上步的可知,要在工程下新建img_h和img_lib文件夹。根据编译的需要逐次将CxImage下的ximage.h xfile.h ximadef.h xiofile.h xmenfile.h ximacfg.h,复制到img_h下,全部复制也可。将上面链接需要的库文件拷贝到img_lib文件夹下。
 

④运行下,看看是否完成了。!

后记
在VC++ 6.0中完成如上,且可在VS2005中直接使用。如要在VS2005中编译,可能需要在工程属性中将字符集设置为Not Set !


----------------------

 


一。原英文网页
http://www./Articles/1300/CxImage

 

二。编译CxImage类库相关说明

1。作者提供的工程文件CxImgLib.dsw (VC++6.0)非常大。如果你只需要能处理其中的几种格式,编译该类库时,你可以在配置的头文件ximcfg.h 中找到一些编译开关选项来关闭一些图像库。JPG、PNG、TIFF中的每一个库,都会向最终程序增加约100KB的内容。而CxImage类库压缩后只有约60KB。所以,你需要谨慎挑选一些你真正需要的类库。

//类库配置文件:ximacfg.h
#define CXIMAGE_SUPPORT_JPG 1
//如果要实现bmp->jpg 则必须打开
#define CXIMAGE_SUPPORT_BMP 1
#define CXIMAGE_SUPPORT_GIF 1
#define CXIMAGE_SUPPORT_JPG 1
//以上为必须打开,下面的随便............
#define CXIMAGE_SUPPORT_PNG 0//不使用它
#define CXIMAGE_SUPPORT_MNG 0
#define CXIMAGE_SUPPORT_ICO 1
#define CXIMAGE_SUPPORT_TIF 0//
#define CXIMAGE_SUPPORT_TGA 0//
#define CXIMAGE_SUPPORT_PCX 0//
#define CXIMAGE_SUPPORT_WBMP 0//
#define CXIMAGE_SUPPORT_WMF 0//
#define CXIMAGE_SUPPORT_J2K 0 // Beta, use JP2
#define CXIMAGE_SUPPORT_JBG 0
//.............

其他的可以不打开


编译该类库有好几个选择的工程,如下图所示:

各工程的作用对应如下:

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 the C libraries
DemoDll : demodll.exe - program linked with cximagecrt.dll
j2k,jasper,jbig,jpeg,png,tiff,zlib : static C libraries
编译这些工程需要耗费几分钟的时间(中间文件可达60MB)。

 

三。在程序中应用CxImage类库进行图像类型转换


在你的VC工程中使用这个类库,要对工程进行如下设置(Project Settings):

|- C/C++
  |- Code Generation
  |   |- Use run-time library : Multithreaded DLL (must be the same for
  |   | all the linked libraries) //应该只要是多线程DLL即可,DEBUG的也行
  |   |- Struct member alignment : must be the same for all the linked libraries
  |- Precompiled headers : not using precompiled headers
  |- Preprocessor
      |- Additional Include Directories: ..\cximage(该处填CxImage里的.h和.cpp文件拷贝并导入工程后所在的文件夹,填写后在工程中include时编译器会查找该文件夹,故include的文件无需路径)
|- Link
    |- General
        |- Object/library modules: png.lib
                                                       jpeg.lib
                                                       zlib.lib
                                                       tiff.lib
                                                       jasper.lib
                                                      cximage.lib (把需要的lib文件从CxImage中拷贝到工程中的lib文件所在的目录)

并且从CxImage中将xfile.h、ximacfg.h、ximadef.h、ximage.cpp、ximage.h、xiofile.h、 xmemfile.cpp、xmemfile.h拷贝到工程文件夹下并将CxImage.h文件加入工程中即可。也可以设置vc6的"tools"中的 "include"路径.

下面介绍应用它进行图像类型转换的方式:

1.从一种图像文件类型转换为另一种文件类型(convert from a format to another)

CxImage image;   // 定义一个CxImage对象

// 从bmp文件转换为jpg文件(bmp -> jpg)
image.Load("image.bmp", CXIMAGE_FORMAT_BMP);   //先装载bmp文件,需要指定文件类型
    // 判断加载的bmp文件是否存在。
if (image.IsValid())......{
       // Returns true if the image has 256 colors and a linear grey scale palette.
    if(!image.IsGrayScale()) image.IncreaseBpp(24);   // param nbit: 4, 8, 24
    image.SetJpegQuality(99);                // 设置图像的压缩质量参数(从0到100,数值越大,质量越高)
    image.Save("image.jpg",CXIMAGE_FORMAT_JPG);          // 把压缩后的图像以jpg文件类型保存起来。
}

// 从png文件转换为tif文件(png -> tif)
image.Load("image.png", CXIMAGE_FORMAT_PNG);
if (image.IsValid())...{
    image.Save("image.tif",CXIMAGE_FORMAT_TIF);
}

2。加载程序资源图像(load an image resource)

即从程序的资源图像中构建CxImage对象,有如下几种方式:

// 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);
或者

//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);
}
或者

//Load a bitmap resource;
HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),
                              MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);
3。在内存缓冲中的图像类型转换

(1)把内存缓冲中的数据解码成一个Image对象(decode an image from memory)

有如下几种方式:
------

CxImage image((BYTE*)buffer,size,image_type);//把内存缓冲buffer中的数据构造成Image对象

//或:

CxMemFile memfile((BYTE*)buffer,size); // 显式使用CxMemFile对象
CxImage image(&memfile,image_type);

//或:

CxMemFile memfile((BYTE*)buffer,size);
CxImage* image = new CxImage();
image->Decode(&memfile,type);


(2)把Image编码存放到内存缓冲中(encode an image in memory)

--------

long size=0;//得到图像大小
BYTE* buffer=0;//存储图像数据的缓冲
image.Encode(buffer,size,image_type);//把image对象中的图像以type类型数据copy到buffer
...
free(buffer);

或:

CxMemFile memfile;            // 显式使用CxMemFile对象
memfile.Open();
image.Encode(&memfile,image_type);
BYTE* buffer = memfile.GetBuffer();
long size = memfile.Size();
...
free(buffer);

---------------

4。处理系统粘贴板中的图像(copy/paste an image)

//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();

5。在picture box中显示一个png格式的文件

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);

四。其它

一个CxImage对象是一个扩展了的位图。作者只是在位图结构上添加了一些起存储信息作用的成员变量。一个CxImage对象(同时)也是一组层。每个层只有在需要时才会分配相应的缓冲区。CxImage::pDib代表着背景图像,CxImage::pAlpha代表着透明层,CxImage:: pSelection代表着被选中的层,被用来创建图像处理时让用户感兴趣的区域。在这三个特殊层面的基础上,你可以增加一些额外的层,这些层可以存储在 CxImage::pLayers中。一般说来,层是一个完整的CxImage对象。因此,你可以构造很复杂的嵌套层。下面是CxImage的一些成员变量:

class CxImage
{
...
protected:
void* pDib;            //包含文件头,调色板等等
BITMAPINFOHEADER head; //标准的文件头(位图)
CXIMAGEINFO info;      //扩展了的信息
BYTE* pSelection;      //用户选中的区域
BYTE* pAlpha;          //alpha通道
CxImage** pLayers;     //通用层
};


typedef struct tagCxImageInfo
{
DWORD   dwEffWidth;       //DWORD 扫描线宽
BYTE*   pImage;           //图像位数
void*   pGhost;           //if this is a ghost, pGhost point to the body
DWORD   dwType;           //原图像的格式
char    szLastError[256]; //出错信息
long    nProgress;        //监视循环的次数
long    nEscape;          //跳出标志
long    nBkgndIndex;      //GIF, PNG, MNG格式使用
RGBQUAD nBkgndColor;      //RGB三原色透明度
BYTE    nQuality;         //JPEG格式使用
long    nFrame;           //TIF, GIF, MNG使用 :实际的帧数
long    nNumFrames;       //TIF, GIF, MNG使用 :帧总数
DWORD   dwFrameDelay;     //GIF, MNG使用
long    xDPI;             //水平分辨率
long    yDPI;             //垂直分辨率
RECT    rSelectionBox;    //选中的矩形区
BYTE    nAlphaMax;        //阴影的最大不透明度
bool    bAlphaPaletteEnabled; //如果调色板中有Alpha通道则为真
bool    bEnabled;         //打开绘图函数
long    xOffset;
long    yOffset;
DWORD   dwEncodeOption;   //一些编码选项
RGBQUAD last_c;           //一些优化选项
BYTE    last_c_index;
bool    last_c_isvalid;
long    nNumLayers;
DWORD   dwFlags;
} CXIMAGEINFO;

关于CxImage类库作者: Davide Pizzolato,一位电子工程师。1984年开始编程,已不在乎使用何种编程语言来开发软件。现就职于Askoll的电子研发部。
官网:http://www./bitmap/cximage.asp
作者:http://www./


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多