Add wxIMAGE_OPTION_GIF_TRANSPARENCY for GIF image loading

Allow to keep the originally defined transparent pixels colour instead
of replacing it with bright pink (which is still the default behaviour).

Closes #18014.
This commit is contained in:
Hugo Elias
2017-12-24 15:14:00 +01:00
committed by Vadim Zeitlin
parent 1ebc28787c
commit 28bf0e8687
4 changed files with 69 additions and 12 deletions

View File

@@ -183,6 +183,7 @@ All (GUI):
- Extend wxRendererNative::DrawGauge() to work for vertical gauges too. - Extend wxRendererNative::DrawGauge() to work for vertical gauges too.
- Add wxHD_BITMAP_ON_RIGHT style to wxHeaderCtrl. - Add wxHD_BITMAP_ON_RIGHT style to wxHeaderCtrl.
- Send wxEVT_DATAVIEW_ITEM_EDITING_DONE when editing was cancelled too. - Send wxEVT_DATAVIEW_ITEM_EDITING_DONE when editing was cancelled too.
- Add wxIMAGE_OPTION_GIF_TRANSPARENCY (Hugo Elias).
wxGTK: wxGTK:

View File

@@ -20,6 +20,10 @@
#define wxIMAGE_OPTION_GIF_COMMENT wxT("GifComment") #define wxIMAGE_OPTION_GIF_COMMENT wxT("GifComment")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY wxS("Transparency")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY_HIGHLIGHT wxS("Highlight")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY_UNCHANGED wxS("Unchanged")
struct wxRGB; struct wxRGB;
struct GifHashTableType; struct GifHashTableType;
class WXDLLIMPEXP_FWD_CORE wxImageArray; // anidecod.h class WXDLLIMPEXP_FWD_CORE wxImageArray; // anidecod.h

View File

@@ -93,6 +93,9 @@ enum wxImagePNGType
#define wxIMAGE_OPTION_CUR_HOTSPOT_Y wxString("HotSpotY") #define wxIMAGE_OPTION_CUR_HOTSPOT_Y wxString("HotSpotY")
#define wxIMAGE_OPTION_GIF_COMMENT wxString("GifComment") #define wxIMAGE_OPTION_GIF_COMMENT wxString("GifComment")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY wxString("Transparency")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY_HIGHLIGHT wxString("Highlight")
#define wxIMAGE_OPTION_GIF_TRANSPARENCY_UNCHANGED wxString("Unchanged")
#define wxIMAGE_OPTION_PNG_FORMAT wxString("PngFormat") #define wxIMAGE_OPTION_PNG_FORMAT wxString("PngFormat")
#define wxIMAGE_OPTION_PNG_BITDEPTH wxString("PngBitDepth") #define wxIMAGE_OPTION_PNG_BITDEPTH wxString("PngBitDepth")
@@ -1287,6 +1290,19 @@ public:
PHOTOMETRIC_MINISWHITE or PHOTOMETRIC_MINISBLACK. The other values PHOTOMETRIC_MINISWHITE or PHOTOMETRIC_MINISBLACK. The other values
are taken care of. are taken care of.
Options specific to wxGIFHandler:
@li @c wxIMAGE_OPTION_GIF_TRANSPARENCY: How to deal with transparent pixels.
By default, the color of transparent pixels is changed to bright pink, so
that if the image is accidentally drawn without transparency, it will be
obvious.
Normally, this would not be noticed, as these pixels will not be rendered.
But in some cases it might be useful to load a GIF without making any
modifications to its colours.
Use @c wxIMAGE_OPTION_GIF_TRANSPARENCY_UNCHANGED to keep the colors correct.
Use @c wxIMAGE_OPTION_GIF_TRANSPARENCY_HIGHLIGHT to convert transparent pixels
to pink (default).
This option has been added in wxWidgets 3.1.1.
@note @note
Be careful when combining the options @c wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, Be careful when combining the options @c wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL,
@c wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, and @c wxIMAGE_OPTION_TIFF_PHOTOMETRIC. @c wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, and @c wxIMAGE_OPTION_TIFF_PHOTOMETRIC.

View File

@@ -130,8 +130,10 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
unsigned long i; unsigned long i;
int transparent; int transparent;
// just in case... // Store the original value of the transparency option, before it is reset
image->Destroy(); // by Create().
const wxString&
transparency = image->GetOption(wxIMAGE_OPTION_GIF_TRANSPARENCY);
// create the image // create the image
wxSize sz = GetFrameSize(frame); wxSize sz = GetFrameSize(frame);
@@ -149,6 +151,14 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
// set transparent colour mask // set transparent colour mask
if (transparent != -1) if (transparent != -1)
{ {
if ( transparency.empty() ||
transparency == wxIMAGE_OPTION_GIF_TRANSPARENCY_HIGHLIGHT )
{
// By default, we assign bright pink to transparent pixels to make
// them perfectly noticeable if someone accidentally draws the
// image without taking transparency into account. Due to this use
// of pink, we need to change any existing image pixels with this
// colour to use something different.
for (i = 0; i < GetNcolours(frame); i++) for (i = 0; i < GetNcolours(frame); i++)
{ {
if ((pal[3 * i + 0] == 255) && if ((pal[3 * i + 0] == 255) &&
@@ -159,14 +169,40 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
} }
} }
pal[3 * transparent + 0] = 255, pal[3 * transparent + 0] = 255;
pal[3 * transparent + 1] = 0, pal[3 * transparent + 1] = 0;
pal[3 * transparent + 2] = 255; pal[3 * transparent + 2] = 255;
image->SetMaskColour(255, 0, 255); image->SetMaskColour(255, 0, 255);
} }
else if ( transparency == wxIMAGE_OPTION_GIF_TRANSPARENCY_UNCHANGED )
{
// Leave the GIF exactly as as it was, just adjust (in the least
// noticeable way, by just flipping a single bit) non-transparent
// pixels colour,
for (i = 0; i < GetNcolours(frame); i++)
{
if ((pal[3 * i + 0] == pal[3 * transparent + 0]) &&
(pal[3 * i + 1] == pal[3 * transparent + 1]) &&
(pal[3 * i + 2] == pal[3 * transparent + 2]))
{
pal[3 * i + 2] ^= 1;
}
}
image->SetMaskColour(pal[3 * transparent + 0],
pal[3 * transparent + 1],
pal[3 * transparent + 2]);
}
else else
{
wxFAIL_MSG( wxS("Unknown wxIMAGE_OPTION_GIF_TRANSPARENCY value") );
}
}
else
{
image->SetMask(false); image->SetMask(false);
}
#if wxUSE_PALETTE #if wxUSE_PALETTE
unsigned char r[256]; unsigned char r[256];