为什么我用GDI+的DrawImage在窗口画png的图,但是颜色却不正常?
hdc = BeginPaint (hwnd, &ps) ;
myGraphics = new Graphics(hdc);
image = new Image(TEXT("0.png"));
myGraphics->DrawImage( image , 0 , 0 );
EndPaint (hwnd, &ps) ;
但是输出的图片却颜色不正常。
可以看出,左边图片浏览器里的蝴蝶明显更加透亮漂亮。而右边窗口里用DrawImage画出的图片很昏暗,偏黑。
请问这是为什么?难道是我的png的问题不够标准?
这是png的下载:http://pan.baidu.com/s/1o6I0G4q
PS:我可以肯定,左边那个透亮的蝴蝶颜色是正常的 展开
(第一次回答问题,希望能拿到分)
PNG的透明效果是通过Alpha混合实现的,通常情况下,Alpha混合使用下面的计算公式:
Dest = Src * (Alpha/255) + Dest * (1-Alpha/255) 【公式1】
变量说明:
Dest 目标像素的RGB值
Src 源像素的RGB值,在这里PNG就是源
Alpha 源像素的Alpha通道值
在Windows编程中,使用函数AlphaBlend实现Alpha混合,但是该函数的Alpha混合公式为:
Dest = Src + Dest * (1-Alpha/255) 【公式2】
(注:实际情况要稍微复杂一点,公式2只是其中一个特例,但也是最常用的一个特例。完整的计算公式参见MSDN中AlphaBlend的帮助)
公式2中,源没有乘以Alpha值,而是直接叠加至目标,显示效果会比公式1亮一些。
因此结论就出来了:
暗一些的蝴蝶使用了公式1
亮一些的蝴蝶使用了公式2(AlphaBlend函数)。下图是调用AlphaBlend的效果:
由于AlphaBlend的特立独行,为了实现与大多数软件一致的显示效果,我在使用AlphaBlend前,都要使用工具软件将PNG中透明背景像素的颜色值变成黑色(0),否则透明背景会显示出来。
原来如此!真是一语惊醒梦中人啊!我考虑过了各种情况,但万万没想到居然是Alpha混合方式不同造成的。果然是学的不扎实啊。
对了,那请问我该如何打开那张png并将其绘制到hdc?(因为我只学过SDK。而SDK下的GDI不支持PNG,所以我想到了用GDI+,但用GDI+的话颜色又不对)我现在是把png转成32位的bmp,然后用AlphaBlend来显示PS:追问居然限制字数。打了一大段只能狂删,好蛋疼
我的实现方法就是你提到的:先将PNG转换成32位BMP,然后调用AlphaBlend显示。
PS:为啥没有采纳我的答案呢?我觉得我说的才是正解啊。
用 Graphics 把 bmp 清空为纯白色或其他色
再把需要画的东西全部都画到 bmp 上
最后把 bmp 画到控件上
这是双缓冲吧。和我说的颜色不正常没关系……甚至我就算通过CreateCompatibleDC创建个hdcMem,然后用Graphics在上面画也同样颜色不正常。
之前网页没显示你的问题中的图片,现在终于可以看到了
那么你再研究研究,如果图片有透明度的话,会和背景相溶,多次重绘不清除原图从头绘制,就会层层叠加,看图片,似乎没有拉伸。要么图片参数有设置地方没设置好,要么就是无清除原图重绘了多次同一图片,我只能这么猜了