为 CBitmap 添加用户可扩展的图像处理支持






4.94/5 (51投票s)
2002年12月15日
3分钟阅读

293062

8778
为CBitmap提供内置的灰度化、旋转、错切、缩放、模糊、锐化、翻转、反色和颜色替换功能,并支持用户自定义的处理插件。

引言
这项工作基于我之前的CEnBitmap类,但已经有了足够的改进,值得单独撰写一篇文章。
我最近阅读了Yves Maurer关于位图旋转的优秀文章(参见致谢部分),这促使我重写了之前为专有3D渲染引擎编写的一个位图后处理库。
由于我之前开发的CEnBitmap类允许加载各种图形格式(从磁盘或通过资源ID),我认为它将为这些进一步的扩展提供理想的载体。
代码
我实现的是一个用户可扩展的位图处理“库”,它内置支持位图的灰度化、旋转、错切、模糊和缩放,使用方法如下所示:
    :
    :
    CEnBitmap bitmap;
    bitmap.LoadImage("c:\......\image.jpg");
    bitmap.GrayImage();
    bitmap.RotateImage(90); // can use radians also
    bitmap.ResizeImage(0.8);
    :
    :
    pMemDC->SelectObject(&bitmap);
    pDC->BitBlt(...);
    :
    :
要定义您自己的图像处理插件,只需从C32BitImageProcessor派生一个新类,并重写虚拟方法CalcDestSize()和ProcessPixels()。
完成此操作后,您可以像这样将插件传递给CEnBitmap对象:
    :
    :
    CEnBitmap bitmap;
    :
    :
    bitmap.ProcessImage(&CMyImageProcessor());
    :
    :
对于多遍处理,您还可以将插件指针数组传递给CEnBitmap,如下所示:
    :
    :
    CEnBitmap bitmap;
    :
    :
    C32BIPArray aProcessors;
    CMyImageProcessor1 p1;
    CMyImageProcessor2 p2;
    CMyImageProcessor3 p3;
    aProcessors.Add(&p1);
    aProcessors.Add(&p2);
    aProcessors.Add(&p3);
    bitmap.ProcessImage(aProcessors);
    :
    :
这样做的好处是只需在操作开始和结束时获取和设置内部HBITMAP位,并尽可能减少内存分配。
速度
尝试一下示例应用程序中的“旋转”按钮,看看它有多快。在200x200的图像上,每次迭代大约需要20-30毫秒。(注意:对于大小相似的图像,翻转和错切插件只需要0-5毫秒)。
实现任何程度的实时处理的关键在于良好的算法(参见Karl Lager的致谢)和在最低级别处理位图(参见Yves Maurer的致谢)。
因此,所有处理都在原始位图位上进行,而不是使用Set/GetPixel(),这将非常慢。
版本 1.2
添加颜色加权会略微降低处理速度,但会带来更好的效果。但是,颜色加权通过布尔属性进行管理,因此您可以选择使用哪种方式。
使用处理器数组进行多次处理可以带来少量改进,因此值得一试(参见示例应用程序了解详细信息)。
示例应用程序
这是一个简单的应用程序,允许您加载各种图像格式并应用内置插件。
注意:插件并不一定按照您选择的顺序应用,而是按照产生最佳结果的顺序应用。
版本 1.2
我已经修改了示例应用程序,以便在旋转时也应用选定的插件,并且可以在运行时启用或禁用。
使用条件
无。
除了 :) 我保留此原创作品的版权,尽管那些在致谢中列出的人所做的工作。
如果您编写了自己的插件,您可以将其发布为自己的原创作品,如果合适,我会将其添加到CEnBitmap接口中,并在本页添加链接。
反馈
我很乐意收到关于以下方面的建议:
- 我将尝试 :) 实现的其他插件。
- 加快现有插件速度的方法
- 改进现有算法输出质量的方法。
版本
- 1.0 2001年12月16日
- 1.1 2001年12月17日- 添加反色功能
- 添加翻转功能
- 添加颜色替换功能
- 加快灰度化速度
 
- 1.2 2001年12月17日- 添加颜色加权(极大地提高了旋转和错切的质量)
- 改进示例应用程序
 
- 1.3 2001年12月18日- 添加锐化功能
- 修复了一些边界条件错误
- 加快模糊速度
- 在示例应用程序中添加了改进的用户控制设置
 
致谢
- Peter Hendrix 的原始IPicture代码的CPicture实现
- Yves Maurer 关于直接处理位图的32位表示的思想的GDIRotate 实现
- Karl Lager 的“快速旋转位图算法”
- Prof. G. Hoffmann 的关于模糊和锐化的帮助的“高斯滤波器”
