Direct2D-模拟颜色键控透明位图 [英] Direct2D - Emulating Color Keyed Transparent Bitmaps
问题描述
我当前正在更新Windows GDI应用程序以使用Direct2D渲染,并且我需要通过颜色键支持透明"位图以实现向后兼容性.
I'm currently updating a Windows GDI application to use Direct2D rendering and I need to support "transparent" bitmaps via color-keying for backwards compatibility.
现在,我正在使用HWND渲染目标和转换后的WIC位图源(到GUID_WICPixelFormat32bppPBGRA).到目前为止,我的计划是从转换后的位图创建一个IWICBitmap,将其Lock(),然后处理每个像素,如果它与颜色键匹配,则将其alpha值设置为0.
Right now I'm working with a HWND render target and a converted WIC bitmap source (to GUID_WICPixelFormat32bppPBGRA). My plan so far is to create a IWICBitmap from the converted bitmap, Lock() it, and then process each pixel setting it's alpha value to 0 if it matches the color key.
这似乎有点蛮力"-这是解决此问题的最佳方法还是有更好的方法?
This seems a bit "brute force" - Is this the best method of approaching this or is there a better way?
为了完整起见,这里摘录了我所做的工作-看起来工作正常,但我愿意接受任何改进!
In the interests of completeness here's an extract of what I went with - looks like it's working fine but I'm open to any improvements!
// 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;
推荐答案
如果只需要处理"位图以进行渲染,则最快的始终是GPU.在Direct2D中,为了简单起见,有效果(ID2D1Effect)位图处理.您可以编写自己的[似乎比较复杂],或使用色键(CLSID_D2D1ChromaKey)
If you only need to "process" the bitmap to render it, then the fastest is always GPU. In Direct2D there are effects (ID2D1Effect) for simple bitmap processing. You can write your own [it seems comparatively complicated], or use one of the built-in effects [which is rather simple]. There is one called chroma-key (CLSID_D2D1ChromaKey).
另一方面,如果需要在CPU上进行进一步处理,它将变得更加复杂.优化您拥有的代码可能会更好.
On the other hand, if you need to do further processing on CPU, it gets more complex. You might be better off optimizing the code you have.
这篇关于Direct2D-模拟颜色键控透明位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!