两个DC,一个作为背景,怎样把另一个半透明地拷到背景上?
我知道是通过逻辑运算来拷贝,可就是不知道怎样做。

解决方案 »

  1.   

    我有,不过刚好不在身边,是用BitBlt(...SRCAND)和BitBlt(...SRCPAINT)共同预算的结果
      

  2.   

    // 显示透明位图/* 设置目标DC的拉伸模式为STRETCH_DELETESCANS,也就是不显示拉伸掉的图像 */
    int srlold = SetStretchBltMode(dcTemp.m_hDC,STRETCH_DELETESCANS);StretchBlt(dcTemp.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),
    dcImage.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),SRCINVERT);//dcImage.m_hDC
    StretchBlt(dcTemp.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),
    dcTrans.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),SRCAND);
    StretchBlt(dcTemp.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),
    dcImage.m_hDC,0,0,DrawRect.Width(),DrawRect.Height(),SRCINVERT);//dcImage.m_hDC
    SetStretchBltMode(pDC->m_hDC,STRETCH_DELETESCANS);
    BitBlt(pDC->m_hDC,DrawRect.left,DrawRect.top,DrawRect.Width(),DrawRect.Height(),
    dcTemp.m_hDC,0,0,SRCCOPY);// 恢复设备描述表原来的设置
    pDC->SetStretchBltMode(srlold);
    -------------------------------
    ::高级编程小书童::
      

  3.   

    To : harry202(harry) 
    dcTrans没有初始化。请问有誰会的?
      

  4.   

    在介绍Alpha通道之前,先来看一个如何利用Alpha值合成两张图片的效果。   
    Image1 Image2 合成图象 Alpha图象合成    Alpha图象合成的方法:合成图象的各点像素值是由用来制作合成图的两张图片的相应点的像素值按一定比例混合而成的,这个比例由Alpha值决定,具体算式见下:            newPixeValR= (pixel1ValR*(255-Alpha)+pixel2ValR*Alpha)/255; // Alpha取值范围从0到255
                newPixeValG= (pixel1ValG*(255-Alpha)+pixel2ValG*Alpha)/255; // Alpha取值范围从0到255
                newPixeValB= (pixel1ValB*(255-Alpha)+pixel2ValB*Alpha)/255; // Alpha取值范围从0到255  从上面的算式可以看出,只要修改Alpha的值,就可以改变合成后的图象中用来合成的两张图片各自所占的比值,改变合成后的显示效果。利用这个方法,我们就可以很轻易的制作出生动的淡入淡出效果和图片间的平滑过度特效。下面给出一个制作合成图的具体源码:BOOL CompoundDIB(HANDLE hDIB,HANDLE hDIBSrc,int alpha)
    {
    LPVOID lpvBuf=NULL; // 目标图象数据指针
    LPVOID lpvBufSrc=NULL; // 源图数据指针// // 源图象信息 // 
    LPBITMAPINFO lpbmif=(LPBITMAPINFO)hDIBSrc; 
    LPBITMAPINFOHEADER lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
    // 计算图象数据偏移量
    UINT nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1<<lpbmifh->biBitCount;
    if ( nColors >256 )
    nColors=0; // 如果颜色数大于256色,则没有调色板
    lpvBufSrc=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD)); 
    int cxSrc=lpbmifh->biWidth; // 源图象宽度
    int cySrc=lpbmifh->biHeight; // 源图象高度
    // 计算图象每行的字节数(图象位数 x 图象宽度,如果不能被2整除则在每行后面添加一个0字节)
    int nBytesPerLineSrc=((cxSrc*lpbmifh->biBitCount+31)&~31)/8; // // 目标图象信息 //
    lpbmif=(LPBITMAPINFO)hDIB;
    lpbmifh=(LPBITMAPINFOHEADER)lpbmif;
    nColors=lpbmifh->biClrUsed ? lpbmifh->biClrUsed : 1<<lpbmifh->biBitCount;
    if ( nColors >256 )
    nColors=0;
    lpvBuf=(LPVOID)((LPBYTE)lpbmif->bmiColors+nColors*sizeof(RGBQUAD));
    int cx=lpbmifh->biWidth;
    int cy=lpbmifh->biHeight;
    int nBytesPerLine=((cx*lpbmifh->biBitCount+31)&~31)/8;LPBYTE lpbPnt=NULL;
    LPBYTE lpbPntSrc=NULL;
    // // 通过alpha值合并两张图象的像素值 //
    // 这里假设是24位真彩色图象,其他深度的图象处理方法可以以次类推
    for ( int y=(cy<cySrc ? cy : cySrc); y>0 ;y-- )
    {
    lpbPnt=(LPBYTE)lpvBuf+nBytesPerLine*(y-1);
    lpbPntSrc=(LPBYTE)lpvBufSrc+nBytesPerLineSrc*(y-1);
    for ( int x=0; x<(cx<cxSrc ? cx : cxSrc); x++ )
    {
    for ( int i=0 ;i<3 ;i++ )
    *lpbPnt++=(*lpbPnt*(255-alpha)+*(lpbPntSrc++)*alpha)/255;
    }
    }
    return TRUE;
    }  回到刚才讨论的问题,如何避免画出的透明图有一个明显的轮廓?想一想刚才介绍的利用Alpha值合成图象方法,如果我们在合成的过程中动态修改Alpha值,使它的轮廓部分从(背景的)0慢慢过度到(前景的)255,这样不就可以使前景逐步地渗透到背景里面了。下面来看看具体做法吧!