CImage使用常见问题

这个类本身应该说是很有用的,但要想用好它还真有些技巧。所谓难者不会,会者不难。

其实介绍总结它用法的文章很多了,之所以我要在写一下,就是从我理解的方式再说一遍。

毕竟大家思路不一样,理解起来可能有偏差。我就是看了msdn后还是没搞明白,又看了很多帖子,综合起来看才搞明白。

首先遇到的问题:为啥用CImage类进行像素操作会这么慢?我本来只是怀疑,但我在http://www.qqgb.com/Program/VC/VCJQ/Program_181956.html找到了答案。和我怀疑的一样。

点对点的图像处理用GetPixel和SetPixel就是自己找慢 这两个都是函数,光参数进出栈的时间都比处理的时间长,更不用说函数内部繁琐的判断和逻辑消耗的时间了 你需要得到CImage对象的Buffer,锁定后直接操作内存

既然这样,那我们怎么得到CImage对象的Buffer?看msdn,以及网上的帖子,都说用GetBits(),但真用对了,还真费了点周折。

主要综合了如下3个帖子。

http://hi.baidu.com/sealmlove2/blog/item/fb615c38202943fb3a87ce82.html

 

http://blog.sina.com.cn/s/blog_487547aa0100an6k.html

 

http://topic.csdn.net/u/20080608/00/4df18305-7852-42ab-a948-88789ea3e65e.html

 

其实GetBits()返回的就是 该类本身一个成员HBITMAP m_hBitmap;中相应的dib数据部分,但具体指向的是哪部分,还有一定的讲究。

typedef struct tagBITMAP { // bm LONG bmType;

                                              LONG bmWidth;

                                              LONG bmHeight;

                                              LONG bmWidthBytes;

                                              WORD bmPlanes;

                                              WORD bmBitsPixel;

                                              LPVOID bmBits; <-----------------------------

} BITMAP;

结合msdn说明 及以上文章,总结出如下方法:

 1、定义数据区指针为BYTE* img_Data img_Data=(BYTE *)m_Image.GetBits()+(m_Image.GetPitch()*(m_Image.GetHeight()-1));

2、if( pitch < 0) pImageData = image . GetPixelAddress(h -1 ,0);

 else pImageData = image. GetPixelAddress( 0,0);

前因后果就不多解释了,那几个文章说得很清楚。

如果一直用这个指针操作的话,需要注意几个问题:

1、了解各行数据的存放位置关系;GetPitch()

2、字节对齐问题;GetPitch()

3、各像素所占位置大小;GetBPP()

其实每次都用 GetPixelAddress 也可以 ,我就是这么用的。

取像素和设置像素颜色信息 上面文章给了函数。

我改造成了如下代码:

BYTE* pByte = (BYTE *)m_bmpImage.GetPixelAddress(x,y);

pixelsB[x+y*w] = *(pByte);

pixelsG[x+y*w] = *(pByte+1);

pixelsR[x+y*w] = *(pByte+2);

 设

BYTE *p = (BYTE*)resImg->GetPixelAddress(x, y);

 *p++ = totalB&0xFF;

 *p++ = totalG&0xFF;

 *p = totalR&0xFF;

 

其他的一些问题在上面的几个文章中,以及msdn上都说得很明白了,我就不再费口舌了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值