如何用GDI+实现AlphaBlend的功能?

解决方案 »

  1.   

    有人告诉我说 AlphaBlend 就是GDI,??????我想放弃AlphaBlend而改用GDI+实现半透明绘图的原因是:
    我程序其它功能大多使用GDI+(比如说读取jpg的Exif信息,不知道这个GDI可以做到吗?),少部分功能如半透明绘图用的是AlphaBlend ,这个函数很方便,但参数是用hDC传入的,无法直接用GDI+传进来(至少我不会),我只能用picturebox来中转,因为它有hDC属性,不过总觉得不太好,至少速度慢了几ms不想在同一工程中用过多的技术,GDI+应该是可以作任何事的,只是我不会~~~拜托各位老大帮帮忙
      

  2.   

    AlphaBlend
      函数功能:该函数用来显示透明或半透明像素的位图。
      函数原型:AlphaBlend(HDC hdcDest,int nXOriginDest,int nYOriginDest,int nWidthDest,int hHeightDest,HDC hdcSrc,int nXOriginSrc,int nYOriginSrc,int nWidthSrc,int nHeightSrc,BLENDFUNCTION blendFunction);
      参数:
      hdcDest:指向目标设备环境的句柄。
      nXoriginDest:指定目标矩形区域左上角的X轴坐标,按逻辑单位。
      nYOriginDest:指定目标矩形区域左上角的Y轴坐标,按逻辑单位。
      nWidthDest:指定目标矩形区域的宽度,按逻辑单位。
      hHeghtdest:指向目标矩形区域高度的句柄,按逻辑单位。
      hdcSrc:指向源设备环境的句柄。
      nXOriginSrc:指定源矩形区域左上角的X轴坐标,按逻辑单位。
      nYOriginSrc:指定源矩形区域左上角的Y轴坐标,按逻辑单位。
      nWidthSrc:指定源矩形区域的宽度,按逻辑单位。
      nHeightSrc:指定源矩形区域的高度,按逻辑单位。
      blendFunction:指定用于源位图和目标位图使用的alpha混合功能,用于整个源位图的全局alpha值和格式信息。源和目标混合功能当前只限为AC_SRC_OVER。
      最后一个参数blendFunction是一个BLENDFUNCTION结构。BLENDFUNCTION结构控制源和目标位图的混合方式,它的BlendOp字段指明了源混合操作,但只支持AC_SRC_OVER,即根据源alpha值把源图像叠加到目标图像上。OpenGL的alpha混合还支持其他的方式,如常量颜色源。下一个字段BlendFalgs必须是0,也是为以后的应用保留的。最后一个字段AlphaFormat有两个选择:0表示常量alpha值,AC_SRC_ALPHA表示每个像素有各自的alpha通道。 
      如果AlphaFormat字段为0,源位图中的所有像素使用同样的常量alpha值,即SourceConstantAlpha字段中的值,该值实际上是0和255,而不是0和1。这里0表示完全透明,255表示完全不透明。目标像素以255-SourceConstantAlpha值作为alpha值。 
      如果AlphaFormat字段的值是AC_SRC_ALPHA,源设备表面的每个像素必须有各自的alpha通道。即,必须是32-bpp的物理设备上下文,或是选中了32-bpp DDB和DIB段的内存设备上下文。这些情况下,每个源像素有4个8位通道:红、绿、蓝和alpha。每个像素的alpha通道和SourceConstantAlpha字段一起用于把源和目标混合起来。实际用于计算的运算式如下: 
      Tmp.Red = Src.Red * SourceConstantAlpha / 255; 
      Tmp.Green = Src.Green * SourceConstantAlpha / 255; 
      Tmp.Blue = Src.Blue * SourceConstantAlpha / 255; 
      Tmp.Alpha = Src.Alpha * SourceConstantAlpha / 255; 
      Beta = 255 – Tmp.alpha; 
      Dst.Red = Tmp.Red + Round((Beta * Dst.Red )/255); 
      Dst.Green = Tmp.Green + Round((Beta * Dst.Green)/255); 
      Dst.Blue = Tmp.Blue + Round((Beta * Dst.Blue )/255); 
      Dst.Alpha = Tmp.Alpha + Round((Beta * Dst.Alpha)/255); 
      返回值:如果函数执行成功,那么返回值为TRUE;如果函数执行失败,那么返回值为FALSE。
      Windows NT:若想获取更多错误信息,请调用GetLastError函数。
      备注:如果源矩形区域与目标矩形区域大小不一样,那么将缩放源位图与目标矩形区域匹配。如果使用SetStretchBltMode函数,那么iStretchMode的值是BLACKONWHITE和WHITEONBLACK,在本函数中,iStretchMode的值自动转换成COLORONCOLOR。目标坐标使用为目标设备环境当前指定的转换方式进行转换。源坐标则使用为源设备环境指定的当前转换方式进行转换。如果源设备环境标识为增强型图元文件设备环境,那么会出错(并且该函数返回FALSE)。如果目标和源位图的色彩格式不同,那么AlphaBlend将源位图转换以匹配目标位图。
      AlphaBlend不支持镜像。如果源或目标区域的宽度或高度为负数,那么调用将失败。
      速查:Windows NT:5.0及以上版本;Windows:98及以上版本;Windows CE:5.0以上支持;头文件:wingdi.h;库文件:作为一个资源包含在msimg32.dll中。 
      

  3.   

    好文先收藏,不过还是没有解决我的问题啊,
    我想用GDI+来完成AlphaBlend,
    最好用GDI+写个函数,参数与其一样的~~,只不过将hDC换成GDI+常用的~~
      

  4.   

    picturebox的hDC的用法与你所说的AlphaBlend的参数hDC是一样的啊,如果你会用hDC属性,那么内存中创建的hDC句柄就会用了啊.
      

  5.   


    问题就在于我不知道如何在没有picturebox的情况下创建或找到hDC,可否明示?
      

  6.   

    能否上载附件?
    我有个测试源代码,热心人可以留Email我发给你,帮我看看~~
      

  7.   


    看来楼主需要补的课程还有很多,大体过程如下
    使用下面API建立hdc
    Declare Function CreateCompatibleDC Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hdc As Long) As Long使用下面API建立位图
    Declare Function CreateCompatibleBitmap Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long通常使用下面API将建立的位图选入HDC
    Declare Function SelectObject Lib "gdi32" Alias "SelectObject" (ByVal hdc As Long, ByVal hObject As Long) As Long这时你可以向hdc中绘图了。用过之后记得使用
    Declare Function DeleteDC Lib "gdi32" Alias "DeleteDC" (ByVal hdc As Long) As LongDeclare Function DeleteObject Lib "gdi32" Alias "DeleteObject" (ByVal hObject As Long) As Long两个API删除建立的句柄和位图。
      

  8.   

    谢谢20楼
    要补的课程的确很多啊,因为时间紧来不及系统学,所以先来这儿问一下~~~
    SelectObject 应该有用,其实我是想用GDI+来解决,因为我用GDI+生成缩略图、读取JPG的EXIF信息等很方便,再混用GDI来使用总觉得代码不“干净”~~,实在没办法也只能这样,没时间了等等再结贴吧
      

  9.   

    你是用vb.net 还是vb6? 
    .net对gdi+有了很好的封装,用vb6就比较麻烦了。AlphaBlend 确实是gdi的,在msimg32.dll里。这个函数需要gdi里的设备上下文,就是dc.
    在gdi+中是面向对象的思想,直接跟Graphics对象打交道.但gdi+为了向下兼容也是提供了dc属性的。Public Declare Function GdipGetDC Lib "gdiplus" (ByVal graphics As Long, hDC As Long) As GpStatus
    Public Declare Function GdipReleaseDC Lib "gdiplus" (ByVal graphics As Long, ByVal hDC As Long) As GpStatus可得到graphics的dc属性。然后就用gdi吧.据说gdi比gdi+快呢.