场景
- 在开发WTL程序时,使用
Gdiplus
绘制PNG
图片. 有时候会遇到以下的情况,绘制一个原图等宽高时,图片在界面上看上去清晰,而当把PNG
缩小宽高之后绘制的图片有明显锯齿,这是什么原因?
说明
-
使用
Gdiplus::Graphics
对象的方法DrawImage
可以绘制原图的Rect
源矩形区域到目标Rect
,也就是如果目标区域和源区域的宽高不一致时,图片会进行缩放绘制。比如我们有一个256x256
的图标,之后我们需要把这个图标缩放绘制到标题栏左上角的位置,而这个位置的图标不只需要32x32
,那么如果没有一个独立的32x32
小图标,我们就需要对这个大图标在调用DrawImage
时指定目标区域的宽高为32x32
,这样Graphics
就会对图标绘制时进行缩放,这样就不需要创建一个新的Gdiplus::Bitmap
进行绘制。 -
Graphics
进行图标缩放绘制时,是由Interpolation Mode
插值模式来决定缩放的质量的。通过graphics.SetInterpolationMode
设置插值模式,通过graphics.GetInterpolationMode
获取当前插值模式。 -
在头文件
<gdiplusenums.h>
里, 具有以下的枚举常量可选.InterpolationModeDefault
的值是默认插值模式值,它等于InterpolationModeLowQuality
, 也等于InterpolationModeBilinear
。而InterpolationModeHighQuality
是默认支持的最大质量选项,这里因为质量最好是InterpolationModeHighQualityBicubic
,那么InterpolationModeHighQuality
即等于InterpolationModeHighQualityBicubic
.typedef enum InterpolationMode { InterpolationModeInvalid, InterpolationModeDefault, // 默认,即等于 InterpolationModeBilinear InterpolationModeLowQuality, // 默认,即等于InterpolationModeBilinear InterpolationModeHighQuality, // 最高质量,即等于InterpolationModeHighQualityBicubic InterpolationModeBilinear, // 双线性插值 InterpolationModeBicubic, // 双三次插值 InterpolationModeNearestNeighbor, // 最近邻插值 InterpolationModeHighQualityBilinear, InterpolationModeHighQualityBicubic } ;
-
可以通过以下代码来验证它们的关系,插值模式的质量和他们的枚举常量值一样,从低到高。如果想设置最高的缩放质量,使用
InterpolationModeHighQualityBicubic
参数,当然质量越高需要计算的资源就越多,随着CPU
的性能提升,这个损耗可以忽略不计。如果跟随系统支持的最高优化算法,可以设置InterpolationModeHighQuality
,目前它的最高值还是等于InterpolationModeHighQualityBicubic
。graphics.SetInterpolationMode(InterpolationModeLowQuality); auto mode = graphics.GetInterpolationMode(); // mode:InterpolationModeBilinear
例子
- 我们看看一个
128x128
的图标使用默认和最高的插值模式,质量相差很大,低质量的外圆有毛刺,高质量的是柔和的。
InterpolationModeBilinear(InterpolationModeLowQuality)
图1:
InterpolationModeHighQualityBicubic(InterpolationModeHighQuality)
图2:
原图
参考
Using Interpolation Mode to Control Image Quality During Scaling