Create native GDI+ representation of wxGraphicsBitmap directly from wxImage
Skip the conversion from wxImage to wxBitmap.
This commit is contained in:
@@ -317,6 +317,7 @@ class WXDLLIMPEXP_CORE wxGDIPlusBitmapData : public wxGraphicsBitmapData
|
||||
public:
|
||||
wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, Bitmap* bitmap );
|
||||
wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, const wxBitmap &bmp );
|
||||
wxGDIPlusBitmapData(wxGraphicsRenderer* renderer, const wxImage& img);
|
||||
~wxGDIPlusBitmapData ();
|
||||
|
||||
virtual Bitmap* GetGDIPlusBitmap() { return m_bitmap; }
|
||||
@@ -1294,6 +1295,67 @@ wxGDIPlusBitmapData::wxGDIPlusBitmapData( wxGraphicsRenderer* renderer,
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
wxGDIPlusBitmapData::wxGDIPlusBitmapData(wxGraphicsRenderer* renderer, const wxImage& img)
|
||||
: wxGraphicsBitmapData(renderer)
|
||||
{
|
||||
m_helper = NULL;
|
||||
m_bitmap = new Bitmap(img.GetWidth(), img.GetHeight(), img.HasAlpha() || img.HasMask() ? PixelFormat32bppPARGB : PixelFormat32bppRGB);
|
||||
|
||||
UINT w = m_bitmap->GetWidth();
|
||||
UINT h = m_bitmap->GetHeight();
|
||||
Rect bounds(0, 0, (INT)w, (INT)h);
|
||||
BitmapData bmpData;
|
||||
m_bitmap->LockBits(&bounds, ImageLockModeWrite, PixelFormat32bppARGB, &bmpData);
|
||||
|
||||
const unsigned char* imgRGB = img.GetData();
|
||||
const unsigned char* imgAlpha = img.GetAlpha();
|
||||
BYTE* pPixLine = reinterpret_cast<BYTE*>(bmpData.Scan0);
|
||||
for ( UINT y = 0; y < h; y++ )
|
||||
{
|
||||
BYTE* pPixByte = pPixLine;
|
||||
for ( UINT x = 0; x < w; x++ )
|
||||
{
|
||||
unsigned char r = *imgRGB++;
|
||||
unsigned char g = *imgRGB++;
|
||||
unsigned char b = *imgRGB++;
|
||||
*pPixByte++ = b;
|
||||
*pPixByte++ = g;
|
||||
*pPixByte++ = r;
|
||||
*pPixByte++ = imgAlpha ? *imgAlpha++ : 255;
|
||||
}
|
||||
|
||||
pPixLine += bmpData.Stride;
|
||||
}
|
||||
|
||||
// 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();
|
||||
pPixLine = reinterpret_cast<BYTE*>(bmpData.Scan0);
|
||||
for ( UINT y = 0; y < h; y++ )
|
||||
{
|
||||
BYTE* pPixByte = pPixLine;
|
||||
for ( UINT x = 0; x < w; x++ )
|
||||
{
|
||||
unsigned char r = *imgRGB++;
|
||||
unsigned char g = *imgRGB++;
|
||||
unsigned char b = *imgRGB++;
|
||||
if ( r == mr && g == mg && b == mb )
|
||||
pPixByte[0] = pPixByte[1] = pPixByte[2] = pPixByte[3] = 0;
|
||||
|
||||
pPixByte += 4;
|
||||
}
|
||||
|
||||
pPixLine += bmpData.Stride;
|
||||
}
|
||||
}
|
||||
|
||||
m_bitmap->UnlockBits(&bmpData);
|
||||
}
|
||||
|
||||
wxImage wxGDIPlusBitmapData::ConvertToImage() const
|
||||
{
|
||||
@@ -2818,12 +2880,6 @@ wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmapFromImage(const wxImage& image)
|
||||
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
|
||||
if ( image.IsOk() )
|
||||
{
|
||||
// Notice that we rely on conversion from wxImage to wxBitmap here but
|
||||
// we could probably do it more efficiently by converting from wxImage
|
||||
// to GDI+ Bitmap directly, i.e. copying wxImage pixels to the buffer
|
||||
// returned by Bitmap::LockBits(). However this would require writing
|
||||
// code specific for this task while like this we can reuse existing
|
||||
// code (see also wxGDIPlusBitmapData::ConvertToImage()).
|
||||
wxGraphicsBitmap gb;
|
||||
gb.SetRefData(new wxGDIPlusBitmapData(this, image));
|
||||
return gb;
|
||||
|
Reference in New Issue
Block a user