Direct2D - 模拟颜色键控透明位图
Posted
技术标签:
【中文标题】Direct2D - 模拟颜色键控透明位图【英文标题】:Direct2D - Emulating Color Keyed Transparent Bitmaps 【发布时间】:2013-01-14 16:24:21 【问题描述】:我目前正在更新 Windows GDI 应用程序以使用 Direct2D 渲染,并且我需要通过颜色键控支持“透明”位图以实现向后兼容性。
现在我正在使用 HWND 渲染目标和转换后的 WIC 位图源(到 GUID_WICPixelFormat32bppPBGRA)。到目前为止,我的计划是从转换后的位图 Lock() 创建一个 IWICBitmap,然后处理每个像素,如果它与颜色键匹配,则将其 alpha 值设置为 0。
这似乎有点“蛮力” - 这是解决这个问题的最佳方法还是有更好的方法?
编辑:为了完整起见,这里是我使用的内容的摘录 - 看起来工作正常,但我愿意接受任何改进!
// pConvertedBmp contains a IWICFormatConverter* bitmap with the pixel
// format set to GUID_WICPixelFormat32bppPBGRA
IWICBitmap* pColorKeyedBmp = NULL;
HRESULT hr = S_OK;
UINT uBmpW = 0;
UINT uBmpH = 0;
pConvertedBmp->GetSize( &uBmpW, &uBmpH );
WICRect rcLock = 0, 0, uBmpW, uBmpH ;
// GetWIC() returns the WIC Factory instance in this app
hr = GetWIC()->CreateBitmapFromSource( pConvertedBmp,
WICBitmapCacheOnLoad,
&pColorKeyedBmp );
if ( FAILED( hr ) )
return hr;
IWICBitmapLock* pBitmapLock = NULL;
hr = pColorKeyedBmp->Lock( &rcLock, WICBitmapLockRead, &pBitmapLock );
if ( FAILED( hr ) )
SafeRelease( &pColorKeyedBmp );
return hr;
UINT uPixel = 0;
UINT cbBuffer = 0;
UINT cbStride = 0;
BYTE* pPixelBuffer = NULL;
hr = pBitmapLock->GetStride( &cbStride );
if ( SUCCEEDED( hr ) )
hr = pBitmapLock->GetDataPointer( &cbBuffer, &pPixelBuffer );
if ( SUCCEEDED( hr ) )
// If we haven't got a resolved color key then we need to
// grab the pixel at the specified coordinates and get
// it's RGB
if ( !clrColorKey.IsValidColor() )
// This is an internal function to grab the color of a pixel
ResolveColorKey( pPixelBuffer, cbBuffer, cbStride, uBmpW, uBmpH );
// Convert the RGB to BGR
UINT uColorKey = (UINT) RGB2BGR( clrColorKey.GetRGB() );
LPBYTE pPixel = pPixelBuffer;
for ( UINT uRow = 0; uRow < uBmpH; uRow++ )
pPixel = pPixelBuffer + ( uRow * cbStride );
for ( UINT uCol = 0; uCol < uBmpW; uCol++ )
uPixel = *( (LPUINT) pPixel );
if ( ( uPixel & 0x00FFFFFF ) == uColorKey )
*( (LPUINT) pPixel ) = 0;
pPixel += sizeof( uPixel );
pBitmapLock->Release();
if ( FAILED( hr ) )
// We still use the original image
SafeRelease( &pColorKeyedBmp );
else
// We use the new image so we release the original
SafeRelease( &pConvertedBmp );
return hr;
【问题讨论】:
【参考方案1】:如果您只需要“处理”位图来渲染它,那么最快的总是 GPU。在 Direct2D 中有 effects (ID2D1Effect) 用于简单的位图处理。你可以自己写[看起来比较复杂],或者使用built-in effects之一[相当简单]。有一个叫chroma-key (CLSID_D2D1ChromaKey)。
另一方面,如果您需要在 CPU 上进行进一步的处理,它会变得更加复杂。优化现有代码可能会更好。
【讨论】:
以上是关于Direct2D - 模拟颜色键控透明位图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SkiaSharp 中使 SKBitmap 位图颜色为透明
SlimDX GDI 位图到 Direct2D 位图的比例约为 1.5 - 2 X