Direct2D-模拟颜色键控透明位图 [英] Direct2D - Emulating Color Keyed Transparent Bitmaps

查看:156
本文介绍了Direct2D-模拟颜色键控透明位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在更新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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆