在向大家介绍CxImage类库之前,先向大家推荐一个优秀的站点:
http://www.codeproject.com
。这个站点有很多值得收藏的文章和源码。本文就是根据此站点相关信息写成。
关于这个类,可以看CodeProject上的文章:http://www.codeproject.com/bitmap/CXImage.asp
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/
CxImage类库是一个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像。有的读者可能说,有那么多优秀的图形库,如OpenIL,FreeImage,PaintLib等等,它们可谓是功能强大,齐全,没必要用其它的类库。但我要说,这些类库基本上没有免费的,使用这些类库,你要被这样那样的许可协议所束缚。在这点上,CxImage类库是完全免费的。另外,在使用上述类库时,你会遇到重重麻烦。因为它们大部分是平台无关的,且用C语言写成,有的还夹杂着基本的C++ wrapper和成堆德编译选项的声明需要你去处理。而CxImage类库在这方面做得很好。还有让我最看好的,就是作者完全公开了
源代码
。相对于那些封装好的图形库和GDI+来说,这一点使我们可以进一步学习各种编解码技术,而不再浮于各种技术的表面。 CxImage类库的结构:
一个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;
要在picture box中显示一个png格式的文件,只需:
CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);
HBITMAP m_bitmap = image.MakeBitmap(m_picture.GetDC()->m_hDC);
m_picture.SetBitmap(m_bitmap);
其它格式则类推。
Examples: how to ...
... convert from a format to another
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);
}
load an image resource
//
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
//
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
//
Load a bitmap resource;
HBITMAP bitmap
=
::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage
*
newImage
=
new
CxImage();
newImage
->
CreateFromHBITMAP(bitmap);
decode an image from memory
CxImage image((BYTE
*
)buffer,size,image_type);
orCxMemFile memfile((BYTE
*
)buffer,size);
CxImage image(
&
memfile,image_type);
orCxMemFile memfile((BYTE
*
)buffer,size);
CxImage
*
image
=
new
CxImage();
image
->
Decode(
&
memfile,type);
encode an image
in
memory
long
size
=
0
;
BYTE
*
buffer
=
0
;
image.Encode(buffer,size,image_type);
free(buffer);
orCxMemFile memfile;
memfile.Open();
image.Encode(
&
memfile,image_type);
BYTE
*
buffer
=
memfile.GetBuffer();
long
size
=
memfile.Size();
free(buffer);
create a multipage TIFF
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);
orFILE
*
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);
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();
需要大家注意的是:整个CxImage类库非常大。如果你只需要能处理其中的几种格式,你可以在主要的头文件ximage.h中找到一些开关选项来关闭一些图像库。JPG、PNG、TIFF中的每一个库,都会向最终程序增加约100KB的内容。而CxImage类库压缩后只有约60KB。所以,你需要谨慎挑选一些你真正需要的类库。作者提供的示例工程在编译后,你会发现如下一些文件: ·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类库前必须设置的一些参数:
Project Settings
|- C/C++
| |- Code Generation
| | |- Use run-time library : Multithreaded DLL (must be the same for
| | | all the linked libraries)
| | |- Struct member alignment : must be the same for all the linked
| | | libraries
| |- Precompiled headers : not using precompiled headers
| |- Preprocessor
| |- Additional Include Directories: ..\cximage
|- Link
|- General
|- Object/library modules: ../png/Debug/png.lib
../jpeg/Debug/jpeg.lib
../zlib/Debug/zlib.lib
../tiff/Debug/tiff.lib
../cximage/Debug/cximage.lib ...
兼容性: - Microsoft Visual C++ 6.0 (static library, DLL and OCX builds) - Microsoft Visual C++ .NET 2003 - Borland C++ Builder version 3 and version 6 - Kdevelop 2.1 with gcc 2.96 (Linux) 关于CxImage类库作者: Davide Pizzolato,一位电子工程师。1984年开始编程,已不在乎使用何种编程语言来开发软件。现就职于Askoll的电子研发部。
posted on 2006-09-10 21:07
Jerry Cat 阅读(1278)
评论(0) 编辑 收藏 引用