gid函数在32bit位图中绘图时没有处理alpha值(默认将alpha值设为0),比如TextOut在一个32bit位图上绘制文字后,文字alpha值是0, 使用AlphaBlend将位图与另外一个32bit位图混合,则因为文字alpha为0而显示不正常。在仍然使用TextOut前提下,有什么办法使其默认alpha为0xFF(乃至任意指定的值)?(起因是修改一个基于gdi函数的小型绘图dll的程序,无法改写dll内部代码, 但程序要增加透明支持。)

解决方案 »

  1.   

    包括bitblt之类的函数也是会出现这种情况的,只有去直接修改32位图像的alpha数据。
      

  2.   

    我也是这么弄的啊 ,但是没遇到问题啊.
    我是通过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
      

  3.   

    不对是通过
    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
      

  4.   

    gid本来就不支持alpha通道啊
    这个恐怕绕不过去
      

  5.   

    怎么发送图片啊 我发送给你 你看下 是这种效果么  就是 windows 下 拖拽选择文件那种
      

  6.   

    用AlphaBlend可以么?这个函数可以贴出各种透明度的颜色吧。。
      

  7.   

    感觉CSDN太菜了,很多人回答问题根本不看作者的说明。悲剧嗄
      

  8.   

    o(︶︿︶)o 唉 下回高手过招 我这种娃娃级别的就不敢参与了。
    自己研究那透明东西研究了2天才出来,寻思你也遇到和我一样的困难了呢,寻思分享以下吧,还被高人一顿骂,有种做好事没好报的感觉啊。
    o(︶︿︶)o 唉 悲剧啊
    o(︶︿︶)o 唉
    o(︶︿︶)o 唉
    o(︶︿︶)o 唉
    o(︶︿︶)o 唉
      

  9.   

    32位位图的确没有alpha通道,被困扰了很久很久.
    后来用GDI+的ImageAttributes::SetColorKey算是解决了这个问题,但需要自己指定透明色.
      

  10.   

    不是打击你积极性,回答问题请看清题意,你的透明代码没错,但请先按LZ说的在绘制前用TextOut画点文字到图片上,然后再透明绘制看看效果。
      

  11.   

    o(︶︿︶)o 唉  我确实写文字了啊  我就是不知道CSDN 怎么发送图片,我的图片上要进行序号标记,就是文件的索引序号和文件名称,都写到了bitmap上。
      

  12.   

    GDI像BitBlt之类的函数说明完全没提到alpha通道的问题~~
    AlphaBlend函数则是比较另类的函数(该函数是在msimg32.lib中的,与一般的GDI函数不同撒)~~
      

  13.   


    小兄弟你可能没有仔细看我的描述。我知道你的代码很好。但是我要的关于TextOut这样的Gdi函数在32bit位图里面绘图的时候,是否可以通过设置gdi属性或者hdc属性或者其它办法,使得TextOut画图时候,自动将所绘文字的alpha值设置成0xFF.
      

  14.   

    TextOut在内存dc里绘制,最终还是使用AlphaBlend把内存dc拷贝过来能得到透明文字把
      

  15.   

    我的库已经实现了在透明位图上用GDI绘制,只是有点取巧。
    其实方案不少:
    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。
      

  16.   

    处理32BMP的alpha提供如下方式可能对楼主有帮助:
    1。可以使用图像处理库CXImage类加载位图然后用Draw函数可以处理图像的alpha
    2。使用AlphaBlend混合位图实现透明处理
      

  17.   

    这个库绘出的图形,可能使用任意颜色,并且已经包含了透明度信息,但其中TextOut的透明度因为Gdi原因而不正确。我不修改库的情况下,需要更正这个问题。
    我现在的做法是绘两次:
    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.
      

  18.   

    我认为没必要怀疑MS隐瞒,没有文档化的方法,GDI确实会把alpha设置为0,想想GDI的历史有多久。GDI本身就不是为透明位图而准备的,后来添加的AlphaBlend也是在单独的img32.dll里实现的,再后来为了一次性解决所有问题,出现了GDI+;到现在微软更不会修改GDI了,因为它主推D2D/DWriter,它能跟GDI无缝集成,而且支持硬件加速,解决了性能问题。
      

  19.   

    楼上那个讲的确实如此,我们现在编程一般都是GDI和GDI+结合在一起,对于PNG图像之类的带有alpha通道的图像直接借助GDI+方便很多,不过效率就 。。楼上讲的D2D还没有怎么听说过啊,只知道D3D啊。
      

  20.   

    我最喜欢贴图看效果了,这个图片就是用GDI绘制出来的,纯纯的GDI,有透明和不透明的地方
    http://www.huyuhan.net/images/layeredwindow.png