Create native D2D representation of wxGraphicsBitmap directly from wxImage

Skip the conversion from wxImage to wxBitmap.
This commit is contained in:
Artur Wieczorek
2021-02-14 00:01:53 +01:00
parent 36ab71301c
commit a25e66d479

View File

@@ -2441,6 +2441,79 @@ public:
} }
#if wxUSE_IMAGE #if wxUSE_IMAGE
wxD2DBitmapResourceHolder(const wxImage& img)
{
const int width = img.GetWidth();
const int height = img.GetHeight();
// Create a compatible WIC Bitmap
WICPixelFormatGUID fmt = img.HasAlpha() || img.HasMask() ? GUID_WICPixelFormat32bppPBGRA : GUID_WICPixelFormat32bppBGR;
HRESULT hr = wxWICImagingFactory()->CreateBitmap(width, height, fmt, WICBitmapCacheOnLoad, &m_srcBitmap);
wxCHECK_HRESULT_RET(hr);
// Copy contents of source image to the WIC bitmap.
WICRect rcLock = { 0, 0, width, height };
wxCOMPtr<IWICBitmapLock> pLock;
hr = m_srcBitmap->Lock(&rcLock, WICBitmapLockWrite, &pLock);
wxCHECK_HRESULT_RET(hr);
UINT rowStride = 0;
hr = pLock->GetStride(&rowStride);
wxCHECK_HRESULT_RET(hr);
UINT bufferSize = 0;
BYTE* pBuffer = NULL;
hr = pLock->GetDataPointer(&bufferSize, &pBuffer);
wxCHECK_HRESULT_RET(hr);
const unsigned char* imgRGB = img.GetData(); // source RGB buffer
const unsigned char* imgAlpha = img.GetAlpha(); // source alpha buffer
BYTE* pBmpBuffer = pBuffer;
for ( int y = 0; y < height; y++ )
{
BYTE* pPixByte = pBmpBuffer;
for ( int x = 0; x < width; x++ )
{
unsigned char r = *imgRGB++;
unsigned char g = *imgRGB++;
unsigned char b = *imgRGB++;
unsigned char a = imgAlpha?*imgAlpha++:255;
// Premultiply RGB values
*pPixByte++ = (b * a + 127) / 255;
*pPixByte++ = (g * a + 127) / 255;
*pPixByte++ = (r * a + 127) / 255;
*pPixByte++ = a;
}
pBmpBuffer += rowStride;
}
// If there is a mask, set the alpha bytes in the target buffer to
// fully transparent or retain original value
if ( img.HasMask() )
{
unsigned char mr = img.GetMaskRed();
unsigned char mg = img.GetMaskGreen();
unsigned char mb = img.GetMaskBlue();
imgRGB = img.GetData();
pBmpBuffer = pBuffer;
for ( int y = 0; y < height; y++ )
{
BYTE* pPixByte = pBmpBuffer;
for ( int x = 0; x < width; x++ )
{
if ( imgRGB[0] == mr && imgRGB[1] == mg && imgRGB[2] == mb )
pPixByte[0] = pPixByte[1] = pPixByte[2] = pPixByte[3] = 0;
imgRGB += 3;
pPixByte += 4;
}
pBmpBuffer += rowStride;
}
}
}
wxImage ConvertToImage() const wxImage ConvertToImage() const
{ {
UINT width, height; UINT width, height;
@@ -2554,6 +2627,12 @@ public:
m_bitmapHolder = new NativeType(bitmap); m_bitmapHolder = new NativeType(bitmap);
} }
wxD2DBitmapData(wxGraphicsRenderer* renderer, const wxImage& image) :
wxGraphicsBitmapData(renderer)
{
m_bitmapHolder = new NativeType(image);
}
wxD2DBitmapData(wxGraphicsRenderer* renderer, NativeType* pseudoNativeBitmap) : wxD2DBitmapData(wxGraphicsRenderer* renderer, NativeType* pseudoNativeBitmap) :
wxGraphicsBitmapData(renderer), m_bitmapHolder(pseudoNativeBitmap) {} wxGraphicsBitmapData(renderer), m_bitmapHolder(pseudoNativeBitmap) {}
@@ -5241,7 +5320,12 @@ wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromNativeBitmap(void* bitmap)
#if wxUSE_IMAGE #if wxUSE_IMAGE
wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromImage(const wxImage& image) wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromImage(const wxImage& image)
{ {
return CreateBitmap(wxBitmap(image)); wxD2DBitmapData* bitmapData = new wxD2DBitmapData(this, image);
wxGraphicsBitmap graphicsBitmap;
graphicsBitmap.SetRefData(bitmapData);
return graphicsBitmap;
} }
wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp)