Fix loading of bitmap with non-pre-multiplied alpha in wxMSW.
Detect when the bitmap file doesn't have pre-multiplied alpha and pre-multiply it ourselves when loading it in this case. Closes #12762. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76007 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -44,6 +44,7 @@ wxMSW:
|
|||||||
- Improve wxMimeTypesManager open command detection (Eric Jensen).
|
- Improve wxMimeTypesManager open command detection (Eric Jensen).
|
||||||
- Make wxFILTER_INCLUDE_LIST in wxTextValidator actually usable.
|
- Make wxFILTER_INCLUDE_LIST in wxTextValidator actually usable.
|
||||||
- Fix handling of selected images in wxBitmapButton (Artur Wieczorek).
|
- Fix handling of selected images in wxBitmapButton (Artur Wieczorek).
|
||||||
|
- Fix loading of bitmap with non-pre-multiplied alpha (Artur Wieczorek).
|
||||||
- Support multiline strings in wxDC::DrawRotatedText() (Artur Wieczorek).
|
- Support multiline strings in wxDC::DrawRotatedText() (Artur Wieczorek).
|
||||||
|
|
||||||
wxOSX/Cocoa:
|
wxOSX/Cocoa:
|
||||||
|
@@ -394,6 +394,48 @@ static bool CheckAlpha(HBITMAP hbmp, HBITMAP* hdib = NULL)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return HDIB containing premultiplied bitmap data if the original bitmap is
|
||||||
|
// not premultiplied, otherwise return NULL.
|
||||||
|
//
|
||||||
|
// Semantics is a bit weird here again because we want to avoid throwing the
|
||||||
|
// wxDIB we create here away if possible.
|
||||||
|
//
|
||||||
|
// Also notice that this function uses a heuristics for determining whether the
|
||||||
|
// original bitmap uses premultiplied alpha or not and can return NULL for some
|
||||||
|
// bitmaps not using premultiplied alpha. And while this should be relatively
|
||||||
|
// rare in practice, we really ought to allow the user to specify this
|
||||||
|
// explicitly.
|
||||||
|
static HBITMAP CreatePremultipliedDIBIfNeeded(HBITMAP hbmp)
|
||||||
|
{
|
||||||
|
// Check if 32-bit bitmap realy has premultiplied RGB data
|
||||||
|
// and premuliply it if necessary.
|
||||||
|
|
||||||
|
BITMAP bm;
|
||||||
|
if ( !::GetObject(hbmp, sizeof(bm), &bm) || (bm.bmBitsPixel != 32) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
wxDIB dib(hbmp);
|
||||||
|
if ( !dib.IsOk() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
unsigned char* pixels = dib.GetData();
|
||||||
|
unsigned char* const end = pixels + 4*dib.GetWidth()*dib.GetHeight();
|
||||||
|
for ( ; pixels < end; pixels += 4 )
|
||||||
|
{
|
||||||
|
const unsigned char a = pixels[3];
|
||||||
|
if ( a > 0 && (pixels[0] > a || pixels[1] > a || pixels[2] > a) )
|
||||||
|
{
|
||||||
|
// Data is certainly not premultiplied by alpha if any of the
|
||||||
|
// values is smaller than the value of alpha itself.
|
||||||
|
PremultiplyPixels(dib.GetData(), end);
|
||||||
|
|
||||||
|
return dib.Detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
||||||
wxBitmapTransparency transp)
|
wxBitmapTransparency transp)
|
||||||
{
|
{
|
||||||
@@ -1113,7 +1155,17 @@ bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
|
|||||||
{
|
{
|
||||||
m_refData = new wxBitmapRefData;
|
m_refData = new wxBitmapRefData;
|
||||||
|
|
||||||
return handler->LoadFile(this, filename, type, -1, -1);
|
if ( !handler->LoadFile(this, filename, type, -1, -1) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// wxBitmap must contain premultiplied data, but external files are not
|
||||||
|
// always in this format, so try to detect whether this is the case and
|
||||||
|
// create a premultiplied DIB if it really is.
|
||||||
|
HBITMAP hdib = CreatePremultipliedDIBIfNeeded(GetHbitmap());
|
||||||
|
if ( hdib )
|
||||||
|
static_cast<wxBitmapRefData*>(m_refData)->Set32bppHDIB(hdib);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#if wxUSE_IMAGE && wxUSE_WXDIB
|
#if wxUSE_IMAGE && wxUSE_WXDIB
|
||||||
else // no bitmap handler found
|
else // no bitmap handler found
|
||||||
|
Reference in New Issue
Block a user