当前位置:编程学习 > VB >>

请教一个关于GDI图形处理的问题

我手里有个函数TransparentBlt(dstDC...srcDC...)


'     将指定的源位图中指定颜色转为透明并在目标中显示出来
'     DstDC 显示结果的目标设备场景句柄
'     SrcDC 包含源位图的源设备场景句柄
'     SrcX, SrcY, SrcW, SrcH 源位图的坐标和宽度、高度
'     DstX, DstY  结果图左上角在目标设备场景中的坐标
'     TransColor  指定要转换为透明的颜色
Private Sub TransparentBlt(DstDC As Long, SrcDC As Long, ByVal SrcX As Integer, ByVal SrcY As Integer, ByVal SrcW As Integer, ByVal SrcH As Integer, DstX As Integer, DstY As Integer, TransColor As Long)
  
    Dim nRet As Long
    Dim MonoMaskDC As Long, hMonoMask As Long
    Dim MonoInvDC As Long, hMonoInv As Long
    Dim ResultDstDC As Long, hResultDst As Long
    Dim ResultSrcDC As Long, hResultSrc As Long
    Dim hPrevMask As Long, hPrevInv As Long
    Dim hPrevSrc As Long, hPrevDst As Long
    Dim OldBC As Long
    Dim OldMode As Integer
           
    '   创建单色屏蔽和反转色屏蔽设备场景
    MonoMaskDC = CreateCompatibleDC(DstDC)
    MonoInvDC = CreateCompatibleDC(DstDC)
    '   为与屏蔽设备场景相关的位图创建单色位图
    hMonoMask = CreateBitmap(SrcW, SrcH, 1, 1, ByVal 0&)
    hMonoInv = CreateBitmap(SrcW, SrcH, 1, 1, ByVal 0&)
    hPrevMask = SelectObject(MonoMaskDC, hMonoMask)
    hPrevInv = SelectObject(MonoInvDC, hMonoInv)
    '   创建保存目标图像的设备场景和位图
    ResultDstDC = CreateCompatibleDC(DstDC)
    ResultSrcDC = CreateCompatibleDC(DstDC)
    '   创建存放最终结果和源的位图
    hResultDst = CreateCompatibleBitmap(DstDC, SrcW, SrcH)
    hResultSrc = CreateCompatibleBitmap(DstDC, SrcW, SrcH)
    hPrevDst = SelectObject(ResultDstDC, hResultDst)
    hPrevSrc = SelectObject(ResultSrcDC, hResultSrc)
    '   将源拷贝到屏蔽设备场景
    OldBC = SetBkColor(SrcDC, TransColor)
    nRet = BitBlt(MonoMaskDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, vbSrcCopy)
    TransColor = SetBkColor(SrcDC, OldBC)
    '   创建屏蔽的反转
    nRet = BitBlt(MonoInvDC, 0, 0, SrcW, SrcH, MonoMaskDC, 0, 0, vbNotSrcCopy)
    '   将背景拷贝到结果中并创建透明效果
    nRet = BitBlt(ResultDstDC, 0, 0, SrcW, SrcH, DstDC, DstX, DstY, vbSrcCopy)
     
    '   通过AND、XOR操作绘制图像使之实现透明背景
    nRet = BitBlt(ResultDstDC, 0, 0, SrcW, SrcH, MonoMaskDC, 0, 0, vbSrcAnd)
    nRet = BitBlt(ResultSrcDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, vbSrcCopy)
    nRet = BitBlt(ResultSrcDC, 0, 0, SrcW, SrcH, MonoInvDC, 0, 0, vbSrcAnd)
    nRet = BitBlt(ResultDstDC, 0, 0, SrcW, SrcH, ResultSrcDC, 0, 0, vbSrcInvert)
    
    '   将结果拷贝到目标设备场景
    nRet = BitBlt(DstDC, DstX, DstY, SrcW, SrcH, ResultDstDC, 0, 0, vbSrcCopy)
        
    ' 释放资源
    hMonoMask = SelectObject(MonoMaskDC, hPrevMask)
    DeleteObject hMonoMask
    hMonoInv = SelectObject(MonoInvDC, hPrevInv)
    DeleteObject hMonoInv
    hResultDst = SelectObject(ResultDstDC, hPrevDst)
    DeleteObject hResultDst
    hResultSrc = SelectObject(ResultSrcDC, hPrevSrc)
    DeleteObject hResultSrc
    DeleteDC MonoMaskDC
    DeleteDC MonoInvDC
    DeleteDC ResultDstDC
    DeleteDC ResultSrcDC
End Sub


它是一个处理透明图片的实例,目的是把源图去掉某个透明色后贴到目标图片上。
如果是处理两个控件,这个函数也就足够了,可是我现在想全部使用内存处理(双缓冲)
于是遇到很棘手的问题了。
我用的都是IPictureDisp类型的变量处理图片,这种类型的参数传入这个函数实现不了。

我试图在函数内使用CreateCompatibleDC(0)和SelectObject(*,*)来还原hDC,但是只能还原一个。

现在想要求教的问题就是,如果我要传入的实参都是IPictureDisp类型,这个函数要怎么改?


你的意思是原和目的DC不用控件?那你应该在函数内再建两个dc,而不是一个啊。

IPictureDisp没有DC,你建了一个DC,然后分别传入不同的IPictureDisp,肯定还是一个DC啊。 我是分别试了,在此函数内再建立1个或2个DC,建立1个的成功了,但是建立2个的失败,不知道是不是方法有误。
我分别测试了3个组合:1、目标DC是变量,源DC是变量(失败)2、目标DC是控件,源DC是变量(成功)3、目标DC是变量,源DC是控件(成功)。这个测试好像告诉我,目标DC不能是变量。

下面这个代码是第二个测试:

    Dim dstDC As Long
    Dim srcDC As Long
    Dim numTmp As Long
    '1 创建设备场景(创建一个与特定设备场景兼容的内存设备场景 DC)
    dstDC = CreateCompatibleDC(0)             '创建一个与屏幕一致的设备场景
    srcDC = CreateCompatibleDC(0)             '创建一个与屏幕一致的设备场景
    '2 创建或取得位图(目标图片的句柄sdstHandle,源图片的句柄srcHandle)
    '3 把位图选入设备环境
    numTmp = SelectObject(dstDC, dstHandle)
    numTmp = SelectObject(srcDC, srcHandle)
    '4 将结果拷贝到目标设备场景


更正一下:
3、目标DC是变量,源DC是控件(失败)
补充:VB ,  API
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,