轉載自:
http://blog.sina.com.cn/s/blog_6281e5750100xdnj.html對于windows系統,EVR/VMR9/VMR渲染器均提供了疊加靜態圖片的接口:
SetAlphaBitmap();
此接口支持靜態圖片的資源使用方式,一種是HDC,一種是SURFACE;
使用發現,如果靜態圖片不規則,是有Alpha通道的不同取值形成,
則通過HDC疊加的會有黑邊存在;
對于EVR/VMR9可采用SURFACE,使用D3D創建,完美水印效果相對容易實現,略過;
對于VMR渲染器,SURFACE需要基于DirectDraw創建離屏表面;
離屏表面創建后,靜態圖片數據使用決定著是否能完美呈現水印效果;
一種是通過離屏表面獲取HDC,操作HDC,把靜態圖片附加給離屏表面,
一種是通過直接操作離屏表面的內存數據地址;
經過幾天的摸索,實現了比較完美的水印效果,代碼如下:
LPDIRECTDRAW7 lpDDraw7;
if(FAILED(DirectDrawCreateEx(NULL, (LPVOID *)&lpDDraw7, IID_IDirectDraw7, NULL)))

{
return ;
}
if (FAILED(lpDDraw7->SetCooperativeLevel(m_hShowWin, DDSCL_NORMAL)))

{
return ;
}
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = xs;
ddsd.dwHeight = ys;
ddsd.ddpfPixelFormat.dwSize =sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags =DDPF_RGB | DDPF_ALPHAPIXELS;
ddsd.ddpfPixelFormat.dwRGBBitCount =32;
ddsd.ddpfPixelFormat.dwRBitMask=0x00ff0000;
ddsd.ddpfPixelFormat.dwGBitMask=0x0000ff00;
ddsd.ddpfPixelFormat.dwBBitMask=0x000000ff;
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask=0xff000000;
if(FAILED(lpDDraw7->CreateSurface(&ddsd, lpSource, NULL)))

{
return ;
}
lpSurface->Restore();
CImage img;
HRESULT result;
result = img.Load(_bstr_t(path));
if(!SUCCEEDED(result))
return ;
LPBYTE lpBits = (LPBYTE)img.GetBits();
int nPitch = img.GetPitch();
int imgWidth = img.GetWidth();
int bpp = img.GetBPP();
if(bpp != 24 && bpp != 32)
return ;
DDSURFACEDESC2 dds;
ZeroMemory(&dds,0,sizeof(dds));
dds.dwSize = sizeof(dds);
if(DD_OK != lpSurface->Lock(NULL, &dds, DDLOCK_WAIT, NULL))
return;
LPBYTE dest = (LPBYTE)dds.lpSurface;
for( int yPos = 0; yPos < img.GetHeight(); yPos++)

{
LPBYTE lpBytes = lpBits + ( yPos * nPitch );
int width = img.GetWidth( ) * (bpp / 8);
for( int xPos = 0; xPos < width; )

{
if(bpp == 24)

{
*dest++ = lpBytes[xPos ];
*dest++ = lpBytes[xPos + 1];
*dest++ = lpBytes[xPos + 2];
*dest++ = 0xff;
xPos += 3 ;
}
else if(bpp == 32)

{
*dest++ = lpBytes[xPos];
xPos ++;
}
}
dest += dds.lPitch - width;
}
lpSurface->Unlock(NULL);靜態圖片的數據賦給離屏表面,上面代碼采用的是操作內存的方式,如果采用
lpSurface->GetDc(&hdc)的方式,然后通過BitBlt方式繪制的話,alpha通道會丟失,達不到水印的完美呈現