使用GDI+进行图像处理
2008-02-26 20:26:59 来源:WEB开发网在此代码段中,重点是GDI+要用宽字符串,所以你要用USES_CONVERSION 和 A2W.。原来的CPicture用Load函数从某个CFile、CArchive、资源ID或流中加载图像。所有Load函数最终都走到从流中加载图像的例程:CPicture::Load(IStream*)。当我开始用Image代替IPicture,并用GDI+函数从流中加载数据时,它不工作。情况真是很糟,令人沮丧。问题出在MFC的CArchiveStream类,这个类在CArchive类之上实现流化。可能是CArchiveStream没有正确实现所有的IStream方法,Image::FromStream无法正确处理基于CArchiveStream的流操作,更糟的是它返回一切OK,但实际上当你试图显示或者删除Image时会失败。 为了解决这个问题,我重写了CPicture::Load(UINT nID),其中用到了CreateStreamOnHGlobal函数。这个API函数很好用,它在一个全局内存块中创建一个流:
// 分配全局内存并在其中创建流
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
这里lpRsrc已经指向内存中的图形资源。所以基本思路是加载图像资源,将它拷贝到全局内存中,在内存上创建一个流,然后用Image::FromStream创建一个图象,有关细节请参见例子源代码。当对象被销毁或某人加载另外的图像时,CPicture自动释放全局内存。对于从CFile或者CArchive加载的情况——其实,根本不需要考虑这种情况。 以上是加载的方法,下面看看如何显示图像,你必须使用GDI+类Graphics——与原来GDI中的设备上下文(HDC或CDC)类似,它也有一个方法DrawImage:
BOOL CPicture::Render(CDC* pDC, CRect rc) const
有关细节请参考源代码。用Image代替IPicture来表现图像要简单一些。Image::GetWidth 和Image::GetHeight分别获得象素的宽度和高度,这正是你所需要代替IPicture中HIMETRIC单位的东东。一般来说,用GDI+很容易编程,例如下面示范了如何旋转:
{
…….
Graphics graphics(pDC->m_hDC);
graphics.DrawImage(m_pImage,
rc.left, rc.top, rc.Width(), rc.Height());
} void CPicture::Rotate(RotateFlipType rft)
{
if (m_pImage) {
m_pImage->RotateFlip(rft);
}
}
这个代码将图像顺时针旋转90度,下面列出了RotateFlipType所有可能的情况: RotateFlipType 选项 // 用于Image::RotateFlip的枚举类型
enum RotateFlipType
{
RotateNoneFlipNone = 0,
Rotate90FlipNone = 1,
Rotate180FlipNone = 2,
Rotate270FlipNone = 3,
RotateNoneFlipX = 4,
Rotate90FlipX = 5,
Rotate180FlipX = 6,
Rotate270FlipX = 7,
RotateNoneFlipY = Rotate180FlipX,
Rotate90FlipY = Rotate270FlipX,
Rotate180FlipY = RotateNoneFlipX,
Rotate270FlipY = Rotate90FlipX,
RotateNoneFlipXY = Rotate180FlipNone,
Rotate90FlipXY = Rotate270FlipNone,
Rotate180FlipXY = RotateNoneFlipNone,
Rotate270FlipXY = Rotate90FlipNone
};
GDI+ 的其它函数用于展开和修剪图像,它甚至还有一个函数Image::GetThumbnailImage用来解决缩略图问题,有兴趣的话不妨自己试一下。 我鼓励大家去研究一下GDI+。有些程序员因为它速度慢而不喜欢它,但是有很多文档中提供了一些技巧来改善它的性能。例如,有一个类叫CachedBitmap,这个类以优化设备的格式保存位图。对于象视频或高端图像编辑等图形敏感的应用程序你可能不会用GDI+来编程(一般都用DirectX),但对于日常的一般图形应用来说,GDI+不失为一种比GDI更好的选择。
更多精彩
赞助商链接