基于Directshow框架使用Windows渲染器VMR叠加水印
生活随笔
收集整理的這篇文章主要介紹了
基于Directshow框架使用Windows渲染器VMR叠加水印
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
對(duì)于windows系統(tǒng),EVR/VMR9/VMR渲染器均提供了疊加靜態(tài)圖片的接口:
SetAlphaBitmap();
?
此接口支持靜態(tài)圖片的資源使用方式,一種是HDC,一種是SURFACE;
使用發(fā)現(xiàn),如果靜態(tài)圖片不規(guī)則,是有Alpha通道的不同取值形成,
則通過HDC疊加的會(huì)有黑邊存在;
?
對(duì)于EVR/VMR9可采用SURFACE,使用D3D創(chuàng)建,完美水印效果相對(duì)容易實(shí)現(xiàn),略過;
對(duì)于VMR渲染器,SURFACE需要基于DirectDraw創(chuàng)建離屏表面;
?
離屏表面創(chuàng)建后,靜態(tài)圖片數(shù)據(jù)使用決定著是否能完美呈現(xiàn)水印效果;
一種是通過離屏表面獲取HDC,操作HDC,把靜態(tài)圖片附加給離屏表面,
一種是通過直接操作離屏表面的內(nèi)存數(shù)據(jù)地址;
?
經(jīng)過幾天的摸索,實(shí)現(xiàn)了比較完美的水印效果,代碼如下: 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); 靜態(tài)圖片的數(shù)據(jù)賦給離屏表面,上面代碼采用的是操作內(nèi)存的方式,如果采用
lpSurface->GetDc(&hdc)的方式,然后通過BitBlt方式繪制的話,alpha通道會(huì)丟失,達(dá)不到水印的完美呈現(xiàn) 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
SetAlphaBitmap();
?
此接口支持靜態(tài)圖片的資源使用方式,一種是HDC,一種是SURFACE;
使用發(fā)現(xiàn),如果靜態(tài)圖片不規(guī)則,是有Alpha通道的不同取值形成,
則通過HDC疊加的會(huì)有黑邊存在;
?
對(duì)于EVR/VMR9可采用SURFACE,使用D3D創(chuàng)建,完美水印效果相對(duì)容易實(shí)現(xiàn),略過;
對(duì)于VMR渲染器,SURFACE需要基于DirectDraw創(chuàng)建離屏表面;
?
離屏表面創(chuàng)建后,靜態(tài)圖片數(shù)據(jù)使用決定著是否能完美呈現(xiàn)水印效果;
一種是通過離屏表面獲取HDC,操作HDC,把靜態(tài)圖片附加給離屏表面,
一種是通過直接操作離屏表面的內(nèi)存數(shù)據(jù)地址;
?
經(jīng)過幾天的摸索,實(shí)現(xiàn)了比較完美的水印效果,代碼如下: 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); 靜態(tài)圖片的數(shù)據(jù)賦給離屏表面,上面代碼采用的是操作內(nèi)存的方式,如果采用
lpSurface->GetDc(&hdc)的方式,然后通過BitBlt方式繪制的話,alpha通道會(huì)丟失,達(dá)不到水印的完美呈現(xiàn) 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的基于Directshow框架使用Windows渲染器VMR叠加水印的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SET NOCOUNT的用法和注意事项
- 下一篇: Xcode生成的可执行文件在哪里