gid函数在32bit位图中绘图时没有处理alpha值(默认将alpha值设为0),比如TextOut在一个32bit位图上绘制文字后,文字alpha值是0, 使用AlphaBlend将位图与另外一个32bit位图混合,则因为文字alpha为0而显示不正常。在仍然使用TextOut前提下,有什么办法使其默认alpha为0xFF(乃至任意指定的值)?(起因是修改一个基于gdi函数的小型绘图dll的程序,无法改写dll内部代码, 但程序要增加透明支持。)
调试欢乐多
我是通过CImage方式取的图像
CDC dcMem;
.
.
.
dcMem.SelectObject(m_selectedBitmap);//拖拽时候的图像,实现Windows下选择文件的蓝色半透明框
BLENDFUNCTION blend = {0};
blend.AlphaFormat = 0;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 100;BOOL b = AlphaBlend((HDC)tempDC,downX,downY,upX-downX,upY-downY,
(HDC)dcMem,0,0,m_bitSize.bmWidth,m_bitSize.bmHeight,blend);//内存DC到内存DC
dc.BitBlt(0,0,m_cx,m_cy,&tempDC,0,0,SRCCOPY);//内存DC到设备DC
CBITMAP m_selectedBitmap;
selectedBitmap.loadbitmap(....
CDC dcMem;
.
.
.
dcMem.SelectObject(m_selectedBitmap);//拖拽时候的图像,实现Windows下选择文件的蓝色半透明框
BLENDFUNCTION blend = {0};
blend.AlphaFormat = 0;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 100;BOOL b = AlphaBlend((HDC)tempDC,downX,downY,upX-downX,upY-downY,
(HDC)dcMem,0,0,m_bitSize.bmWidth,m_bitSize.bmHeight,blend);//内存DC到内存DC
dc.BitBlt(0,0,m_cx,m_cy,&tempDC,0,0,SRCCOPY);//内存DC到设备DC
这个恐怕绕不过去
自己研究那透明东西研究了2天才出来,寻思你也遇到和我一样的困难了呢,寻思分享以下吧,还被高人一顿骂,有种做好事没好报的感觉啊。
o(︶︿︶)o 唉 悲剧啊
o(︶︿︶)o 唉
o(︶︿︶)o 唉
o(︶︿︶)o 唉
o(︶︿︶)o 唉
后来用GDI+的ImageAttributes::SetColorKey算是解决了这个问题,但需要自己指定透明色.
AlphaBlend函数则是比较另类的函数(该函数是在msimg32.lib中的,与一般的GDI函数不同撒)~~
小兄弟你可能没有仔细看我的描述。我知道你的代码很好。但是我要的关于TextOut这样的Gdi函数在32bit位图里面绘图的时候,是否可以通过设置gdi属性或者hdc属性或者其它办法,使得TextOut画图时候,自动将所绘文字的alpha值设置成0xFF.
其实方案不少:
1、用GDI+的Graphics接管HDC或者位图,用GDI+来绘制,它会帮你处理A值。性能要看需求,够用就行了。
2、用D3DX的API,创建一个不带ALPHA通道的纹理,设置一个特定的背景色,在上面随意使用GDI函数,用关键色方式复制到另一个纹理中(过滤掉背景色),纹理贴图时使用固定的A值就可以了。
3、我的方案:用自定义的内存区域创建一个32位表面;填充背景色(A值=1);用GDI随意绘制;用MMX/SSE指令把位图数据中的A值全减1。现在这个表面就是一个背景A为0,绘制区域A为255的带ALPHA通道的位图,用到哪里都可以。用MMX的性能很不错,处理一张1024*768的32位位图的A通道,几毫秒就完成了。不敢藏私,希望对你有用。
其实还有一些信息可以参考,VISTA已经有一些API能够保护ALPHA值不被GDI篡改,但无法用于2000/XP。
1。可以使用图像处理库CXImage类加载位图然后用Draw函数可以处理图像的alpha
2。使用AlphaBlend混合位图实现透明处理
我现在的做法是绘两次:
1、将位图DibSection_1的alpha通道全部置0x00,使用库的Draw函数绘图;
2、将位图DibSection_2的alpha通道全部置0xFF, 使用库的Draw函数绘图(得到与步骤1中除alpha通道外完全相同的图);
3、对DibSection_1的r通道进行运算:
DibSection_1[(x*width + y)][3] = 0xFF - DibSection_2[(x*width + y)][0] + DibSection_1[(x*width + y)][0]。此处进行透明度修正耗时不算大,而是每次Draw调用耗时巨大,这里调用两次,效率太低。另外,尝试使用hook TextOut, ExtTextOut, DrawText等几个函数也成功了(但此种做法稳定性和可移植性都差)。
故希望找到文档化的办法(比如设置gdi参数/模式),使得TextOut这样的函数默认将alpha值设置为0xFF.
http://www.huyuhan.net/images/layeredwindow.png