Direct2D — эмуляция цветовых прозрачных растровых изображений

В настоящее время я обновляю приложение Windows GDI для использования визуализации Direct2D, и мне нужно поддерживать «прозрачные» растровые изображения с помощью цветовой клавиатуры для обратной совместимости.

Прямо сейчас я работаю с целью рендеринга HWND и преобразованным источником растрового изображения WIC (в GUID_WICPixelFormat32bppPBGRA). Пока я планирую создать IWICBitmap из преобразованного растрового изображения, Lock () и обработать каждый пиксель, установив его альфа-значение в 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;

4

Решение

Если вам нужно только «обработать» растровое изображение для его рендеринга, то самым быстрым всегда будет GPU. В Direct2D есть последствия (ID2D1Effect) для простой обработки растрового изображения. Вы Можно написать свой собственный [кажется, сравнительно сложным], или использовать один из встроенные эффекты [что довольно просто]. Есть один называется хроматический ключ (CLSID_D2D1ChromaKey).

С другой стороны, если вам нужно выполнить дополнительную обработку на процессоре, она становится более сложной. Возможно, вам лучше оптимизировать код, который у вас есть.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]