摘 要 针对直接运用StretchDIBits函数进行图像缩放时的视觉失真问题,利用GDI函数设计一个图像缩放函数,使用该函数得到的视觉效果优于直接使用StretchDIBits。文中以位图缩放显示为例,对如何使用该函数进行说明。
关键词 图像缩放;图像失真;GDI函数;位图;VC++
1 前言
图像显示是人们感知图像信息的最直观方式之一。文献[1]介绍了如何在VC++环境下设计一个位图浏览器进行多幅图像显示。由于图像大小与图像显示设备分辨率大小往往不一致,为了在显示设备上更好地浏览图像,往往需要将图像缩放到适合于显示设备分辨率大小的尺寸。在VC++中,实现图像缩放显示的方法主要有两大类:(1)根据图像几何变换公式,运用插值方法生成缩放后的图像[2];(2)直接利用VC++提供的函数实现图像缩放。第一类方法需要清晰理解图像的几何变换关系及插值计算方法,优点是可以根据图像质量要求设计各种缩放方法(最邻近方法、双线性插值、样条插值等),适合于研究算法用。第二类方法编程简单,代码效率高,更适合于实际工程应用。VC++中提供的函数StretchDIBits或BitBlt,可实现图像按任意比例大小缩放,然而图像缩放后会出现明显的视觉失真,其中图像缩小时尤为明显。针对这一不足,运用图形设备接口(GDI)函数实现图像平滑缩放,视觉效果优于直接运用函数StretchDIBits或BitBlt。
2 步骤
减轻图像缩放失真的思路是专门分配一块内存单元储存缩放后的图像数据,在显示图像阶段,采用显示单元的数据进行位图绘制,而不使用原来的位图数据。利用GDI函数实现缩放的主要步骤包括:(1)计算缩放后的图像大小;(2)根据缩放大小,为显示单元分配内存空间;(3)创建用于说明显示单元的位图信息头;(4)利用CreateDIBSection分别创建图像缩放前后的设备无关位图(DIB);(5)将缩放前后的DIB载入上下文设备;(6)设置上下文设备的图像伸缩模式;(7)运用StretchBlt将源图像对应的DIB拷贝到缩放后的DIB;(8)释放内存资源。
3 函数说明
为了便于读者理解,先介绍后续使用到的几个GDI函数。
(1)HBITMAP CreateDIBSection
HDC hdc, CONST BITMAPINFO *pbmi,UINT iUsage, VOID *ppvBits, HANDLE hSection, DWORD dwOffset
hdc为上下文设备句柄,pbmi为BITMAPINFO类型的结构指针,iUsage指明使用的颜色类型:RGB颜色(DIB_RGB_COLORS)或调色板索引(DIB_PAL_COLORS),ppvBits存放位图图像位值的地址,hSection为可选的文件映射对象的句柄,dwOffset表示文件映射对象中位图位值的偏移量。该函数用于创建可直接写入的DIB,执行成功时返回DIB位图句柄,失败则返回NULL。
|