• MFC/VC CxImage 简单配置与使用 (完整版)


    如果本篇文章还不能解决你在生成解决方案以及便宜过程中的问题 请参阅:
    
    http://blog.csdn.net/afterwards_/article/details/7997385 我个人配置过来成功运行的经验.
    
    CxImage是一个十分强大的图形库,我们在PC端上开发GUI程序时,时常会用到位图之外的各种格式的图片,然而令我们郁闷的是在Windows平台上的GDI对一些图片格式支持的很差,比如png格式!尽管mfc上有一个CImage类来解决这个问题,但是,CImage对png图片的支持其实也不怎么样,尤其是图片带半透明效果时,CImage基本上就没法处理或处理的很差。
    
    当然,我们也不是没有解决的方法,一种是我们自己解析png协议,然后将png图片转成1张或2张位图,这种方法一劳永逸,但是也太劳了….>_<
    
    另一种是使用GDIPLUS(也就是GDI+),它可以解决PNG的问题,但似乎渲染效率不是很高,而且,貌似CPU占用也稍微高了一点(当然,我觉得也有可能是我使用的时候在某些方面用得不好,尽管双缓冲什么的都用了,但是赶紧CPU的占用还是高了点)。
    
    还有一种就是是使用CxImage,我们下面就简单的介绍一下如何使用CxImage(之所以简单是因为我也是刚刚能画出png图片,还算不上会用,哈哈 ^0^1,下载CxImage,可以从http://www.xdp.it/cximage/600/cximage600_full.7z上下载,这个是最新的6.00版本。(ps 这里补充一句,转载到文章的时候,这里是6.0版本,而最新的我目前使用的是7.0,并且我配置的经验可能和6.0的不同)
    
    2,解压压缩包,然后用开发工具打开(我用的是VS2005,你用VC6也一样能打开),随后编译项目记住要把CxImage以及那些代表图片格式的项目都编译一遍,这样在它们相应目录下的Debug下就会生成相应的lib,如果你想看看demo的效果,那你必须先编译之前说的那些项目,否则demo会找不到相应的lib而无法执行。
    
    3,将所有的lib放在某个文件夹下,比如 E:libspng.lib jpeg.lib zlib.libtiff.lib jbig.lib jasper.lib mng.lib cximage.lib,这里要说明的是由于cximage比较大,如果你只是希望支持众多格式中的几种,请在编译CxImage项目时,在ximacfg.h中更改所要支持的格式标记,1为支持,0为不支持。我把除了PNG以外的格式都标记为不支持了,这样cximage.lib的大小约为1.57M,如果全支持,好像是2M多。另外说一下,如果只是为了支持png图片,那么依赖的包也只有zlib.lib和png.lib。
    
    4,在项目中加载这些lib,具体步骤如下
    
    选项->工具->项目和解决方案->VC++目录
    
    库文件:增加:   E:lib
    
    包含文件:增加:(your CxImagedir)CxImage
    
    然后在你的工程中:
    
    项目->属性->配置属性->链接器->输入->附加依赖项:增加:
    
    cximage.lib jpeg.lib png.lib tiff.libj2k.lib jasper.lib jbig.lib zlib.lib
    
    在项目->属性->配置属性->常规
    
    MFC使用:在共享DLL中使用MFC
    
    字符集:使用多字节字符集
    
    在项目->属性->配置属性->C/C++->代码生成
    
    运行时库: /MD
    结构成员对齐: 16字节
    
    预编译头:不使用预编译头
    
    这些都弄完之后,你应该就可以使用CxImage了,简单是例子如下:
    
    #include “ximage.h”
    
    CxImage image;
    
    CString filename("c:\1.png");
    image.Load(filename,CXIMAGE_FORMAT_PNG);
    
    image.Draw(hdc,0,0);
    
     
    
     
    
    一。CxImage类库简介
    
    这只是翻译了CxImage开源项目主页上的部分简介及简单使用。
    
    CxImage类库是一 个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像。有的读者可能说,有那么多优秀的图形库,如OpenIL,FreeImage,PaintLib等等,它们可谓是功能强大,齐全,没必要用其它的类库。但我要说,这些类库基本上没有免费的,使用这些类库,你要被这样那样的许可协议所 束缚。在这点上,CxImage类库是完全免费的。另外,在使用上述类库时,你会遇到重重麻烦。因为它们大部分是平台无关的,且用C语言写成,有的还夹杂 着基本的C++ wrapper和成堆德编译选项的声明需要你去处理。而CxImage类库在这方面做得很好。还有让我最看好的,就是作者完全公开了源代码。相对于那些封 装好的图形库和GDI+来说,这一点使我们可以进一步学习各种编解码技术,而不再浮于各种技术的表面。
    
    CxImage是一个可以用于MFC 的C++类,可以打开,保存,显示,转换各种格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA,WMF, WBMP, JBG, J2K 等格式的文件。可以实现BMP<->JPG,PNG <>TIFF格式等等的转换。
    
    既可以实现图像文件的类型转换,也可以实现在内存图像数据的类型转换,并且使用很方便。
    
    它的作者是:Davide Pizzolato ,主页: http://www.xdp.it/
    
    首先,到http://www.codeproject.com/bitmap/CXImage.asp下载它的源文件和Demo例子.
    
    注: 在Codeproject下载这个类,你得先注册一下,因为这个类可是含金量比较高的,下载量比较大的,当然你也会很高兴成为CodeProject的一名成员的,她不收你的费.授权:
    
    License
    The class CxImage is free; as for the TIFF, JPEG, PNGand ZLIB libraries : "If you use this source code in a product,acknowledgment is not required but would be appreciated."
    
    CxImage is open source and licensedunder the zlib license . In anutshell, this means that you can use the code however you wish, as long as youdon't claim it as your own.
    
    由于很多人上codeproject的时候,老是上不去,所以,你也可以去这个类库的作者--DavidePizzolato的主页去下载
    
    他的主页还有另外的源代码,有兴趣的也可以看看.
    
     
    
    二。编译CxImage类库
    
    作者已经提供了整个类库配置的工程文件CxImgLib.dsw(VC++6.0),只要打开它进行编译即可。需要大家注意的是:整个CxImage类库非常大。如果你只需要能处理其中的几种格式,编译该类库时,你可以在配置的头文件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 - staticlibrary
    
    ·  CxImageCrtDll : cximagecrt.dll - DLLnot using mfc
    
    ·  CxImageMfcDll : cximage.dll - DLLusing mfc
    
    ·  Demo : demo.exe - program linkedwith cximage.lib and the C libraries
    
    ·  DemoDll : demodll.exe - programlinked withcximagecrt.dll
    
    ·  j2k,jasper,jbig,jpeg,png,tiff,zlib : static Clibraries
    
    编译这些工程需要耗费几分钟的时间(中间文件可达60MB)。
    
     
    
    三。在程序中应用CxImage类库进行图像类型转换
    
    在你的VC工程中使用这个类库,要对工程进行如下设置(ProjectSettings):
    
    |- C/C++
    |   |- Code Generation
    |   |   |- Use run-time library : Multithreaded DLL (mustbe the same for 
    |   |   |  all the linked libraries)  //应该只要是多线程DLL即可,DEBUG的也行
    |   |   |- Struct member alignment : must be the same forall 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 animage 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 animage 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类库作者: DavidePizzolato,一位电子工程师。1984年开始编程,已不在乎使用何种编程语言来开发软件。现就职于Askoll的电子研发部。
    
    关于CxImage类库更多的信息,请到它的官网或作者主页去了解。
    
    官网:http://www.codeproject.com/bitmap/cximage.asp
    
    作者:http://www.xdp.it/
    
     
  • 相关阅读:
    C# 图片与Base64的相互转化
    LeetCode 303. Range Sum Query – Immutable
    LeetCode 300. Longest Increasing Subsequence
    LeetCode 292. Nim Game
    LeetCode 283. Move Zeroes
    LeetCode 279. Perfect Squares
    LeetCode 268. Missing Number
    LeetCode 264. Ugly Number II
    LeetCode 258. Add Digits
    LeetCode 257. Binary Tree Paths
  • 原文地址:https://www.cnblogs.com/chenzuoyou/p/3288520.html
Copyright © 2020-2023  润新知