Applied part of #10034: wxImage::ConvertToDisabled()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62099 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2009-09-24 20:05:33 +00:00
parent cc3d673a84
commit 198c264dbc
10 changed files with 288 additions and 61 deletions

View File

@@ -175,6 +175,9 @@ public:
virtual wxBitmap GetSubBitmap(const wxRect& rect) const = 0; virtual wxBitmap GetSubBitmap(const wxRect& rect) const = 0;
// Convert to disabled (dimmed) bitmap.
wxBitmap ConvertToDisabled(unsigned char brightness = 255);
virtual bool SaveFile(const wxString &name, wxBitmapType type, virtual bool SaveFile(const wxString &name, wxBitmapType type,
const wxPalette *palette = NULL) const = 0; const wxPalette *palette = NULL) const = 0;
virtual bool LoadFile(const wxString &name, wxBitmapType type) = 0; virtual bool LoadFile(const wxString &name, wxBitmapType type) = 0;

View File

@@ -15,7 +15,6 @@
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/gdiobj.h" #include "wx/gdiobj.h"
class WXDLLIMPEXP_FWD_CORE wxColour; class WXDLLIMPEXP_FWD_CORE wxColour;
// A macro to define the standard wxColour constructors: // A macro to define the standard wxColour constructors:
@@ -148,6 +147,22 @@ public:
bool Ok() const { return IsOk(); } bool Ok() const { return IsOk(); }
#endif #endif
// manipulation
// ------------
// These methods are static because they are mostly used
// within tight loops (where we don't want to instantiate wxColour's)
static void MakeMono (unsigned char* r, unsigned char* g, unsigned char* b, bool on);
static void MakeDisabled(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char brightness = 255);
static void MakeGrey (unsigned char* r, unsigned char* g, unsigned char* b); // integer version
static void MakeGrey (unsigned char* r, unsigned char* g, unsigned char* b,
double weight_r, double weight_g, double weight_b); // floating point version
static unsigned char AlphaBlend (unsigned char fg, unsigned char bg, double alpha);
static void ChangeLightness(unsigned char* r, unsigned char* g, unsigned char* b, int ialpha);
wxColour ChangeLightness(int ialpha) const;
// old, deprecated // old, deprecated
// --------------- // ---------------

View File

@@ -354,13 +354,17 @@ public:
unsigned char r2, unsigned char g2, unsigned char b2 ); unsigned char r2, unsigned char g2, unsigned char b2 );
// Convert to greyscale image. Uses the luminance component (Y) of the image. // Convert to greyscale image. Uses the luminance component (Y) of the image.
// The luma value (YUV) is calculated using (R * lr) + (G * lg) + (B * lb), defaults to ITU-T BT.601 // The luma value (YUV) is calculated using (R * weight_r) + (G * weight_g) + (B * weight_b), defaults to ITU-T BT.601
wxImage ConvertToGreyscale( double lr = 0.299, double lg = 0.587, double lb = 0.114 ) const; wxImage ConvertToGreyscale(double weight_r, double weight_g, double weight_b) const;
wxImage ConvertToGreyscale(void) const;
// convert to monochrome image (<r,g,b> will be replaced by white, // convert to monochrome image (<r,g,b> will be replaced by white,
// everything else by black) // everything else by black)
wxImage ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const; wxImage ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const;
// Convert to disabled (dimmed) image.
wxImage ConvertToDisabled(unsigned char brightness = 255) const;
// these routines are slow but safe // these routines are slow but safe
void SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b ); void SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b );
void SetRGB( const wxRect& rect, unsigned char r, unsigned char g, unsigned char b ); void SetRGB( const wxRect& rect, unsigned char r, unsigned char g, unsigned char b );

View File

@@ -498,6 +498,12 @@ public:
*/ */
wxSize GetSize() const; wxSize GetSize() const;
/**
Returns disabled (dimmed) version of the bitmap.
@since 2.9.0
*/
wxBitmap ConvertToDisabled(unsigned char brightness = 255) const;
/** /**
Gets the width of the bitmap in pixels. Gets the width of the bitmap in pixels.

View File

@@ -213,6 +213,54 @@ public:
colours and alpha values. colours and alpha values.
*/ */
bool operator ==(const wxColour& colour) const; bool operator ==(const wxColour& colour) const;
/**
Assign 0 or 255 to rgb out parameters.
@since 2.9.0
*/
static void MakeMono(unsigned char* r, unsigned char* g, unsigned char* b, bool on);
/**
Create a disabled (dimmed) colour from (in/out) rgb parameters.
@since 2.9.0
*/
static void MakeDisabled(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char brightness = 255);
/**
Create a grey colour from (in/out) rgb parameters using integer arithmetic.
@since 2.9.0
*/
static void MakeGrey(unsigned char* r, unsigned char* g, unsigned char* b);
/**
Create a grey colour from (in/out) rgb parameters using floating point arithmetic.
Defaults to using the standard ITU-T BT.601 when converting to YUV, where every pixel equals
(R * @a weight_r) + (G * @a weight_g) + (B * @a weight_b).
@since 2.9.0
*/
static void MakeGrey(unsigned char* r, unsigned char* g, unsigned char* b,
double weight_r, double weight_g, double weight_b);
/**
Blend colour, taking alpha into account.
@since 2.9.0
*/
static unsigned char AlphaBlend(unsigned char fg, unsigned char bg, double alpha);
/**
ChangeLightness() is a utility function that simply darkens
or lightens a color, based on the specified percentage
ialpha of 0 would be completely black, 200 completely white
an ialpha of 100 returns the same colour
@since 2.9.0
*/
static void ChangeLightness(unsigned char* r, unsigned char* g, unsigned char* b, int ialpha);
/**
wxColour wrapper for ChangeLightness(r,g,b,ialpha).
@since 2.9.0
*/
wxColour ChangeLightness(int ialpha) const;
}; };

View File

@@ -171,6 +171,12 @@ public:
*/ */
virtual ~wxIcon(); virtual ~wxIcon();
/**
Returns disabled (dimmed) version of the icon. MSW only.
@since 2.9.0
*/
wxIcon ConvertToDisabled(unsigned char brightness = 255) const;
/** /**
Copies @a bmp bitmap to this icon. Copies @a bmp bitmap to this icon.
Under MS Windows the bitmap must have mask colour set. Under MS Windows the bitmap must have mask colour set.

View File

@@ -847,9 +847,15 @@ public:
The returned image uses the luminance component of the original to The returned image uses the luminance component of the original to
calculate the greyscale. Defaults to using the standard ITU-T BT.601 calculate the greyscale. Defaults to using the standard ITU-T BT.601
when converting to YUV, where every pixel equals when converting to YUV, where every pixel equals
(R * @a lr) + (G * @a lg) + (B * @a lb). (R * @a weight_r) + (G * @a weight_g) + (B * @a weight_b).
*/ */
wxImage ConvertToGreyscale(double lr = 0.299, double lg = 0.587, double lb = 1.114) const; wxImage ConvertToGreyscale(double weight_r, double weight_g, double weight_b) const;
/**
Returns a greyscale version of the image.
@since 2.9.0
*/
wxImage ConvertToGreyscale() const;
/** /**
Returns monochromatic version of the image. Returns monochromatic version of the image.
@@ -859,6 +865,12 @@ public:
*/ */
wxImage ConvertToMono(unsigned char r, unsigned char g, unsigned char b) const; wxImage ConvertToMono(unsigned char r, unsigned char g, unsigned char b) const;
/**
Returns disabled (dimmed) version of the image.
@since 2.9.0
*/
wxImage ConvertToDisabled(unsigned char brightness = 255) const;
//@} //@}

View File

@@ -135,6 +135,16 @@ public:
void OnExit() { wxBitmap::CleanUpHandlers(); } void OnExit() { wxBitmap::CleanUpHandlers(); }
}; };
wxBitmap wxBitmapBase::ConvertToDisabled(unsigned char brightness) const
{
wxBitmap bmp;
#if wxUSE_IMAGE
wxImage image = ConvertToImage();
bmp = wxBitmap(image.ConvertToDisabled(brightness));
#endif
return bmp;
}
IMPLEMENT_DYNAMIC_CLASS(wxBitmapBaseModule, wxModule) IMPLEMENT_DYNAMIC_CLASS(wxBitmapBaseModule, wxModule)
#endif // wxUSE_BITMAP_BASE #endif // wxUSE_BITMAP_BASE

View File

@@ -149,6 +149,97 @@ wxString wxColourBase::GetAsString(long flags) const
return colName; return colName;
} }
// static
void wxColourBase::MakeMono(unsigned char* r, unsigned char* g, unsigned char* b,
bool on)
{
*r = *g = *b = on ? 255 : 0;
}
// static
void wxColourBase::MakeGrey(unsigned char* r, unsigned char* g, unsigned char* b
/*, unsigned char brightness */
)
{
*r = *g = *b = (wxByte)(((*b)*117UL + (*g)*601UL + (*r)*306UL) >> 10);
}
// static
void wxColourBase::MakeGrey(unsigned char* r, unsigned char* g, unsigned char* b,
double weight_r, double weight_g, double weight_b)
{
double luma = (*r) * weight_r + (*g) * weight_g + (*b) * weight_b;
*r = *g = *b = (wxByte)wxRound(luma);
}
// static
void wxColourBase::MakeDisabled(unsigned char* r, unsigned char* g, unsigned char* b,
unsigned char brightness)
{
//MakeGrey(r, g, b, brightness); // grey no-blend version
*r = AlphaBlend(*r, brightness, 0.4);
*g = AlphaBlend(*g, brightness, 0.4);
*b = AlphaBlend(*b, brightness, 0.4);
}
// AlphaBlend is used by ChangeLightness and MakeDisabled
// static
unsigned char wxColourBase::AlphaBlend(unsigned char fg, unsigned char bg,
double alpha)
{
double result = bg + (alpha * (fg - bg));
result = wxMax(result, 0.0);
result = wxMin(result, 255.0);
return (unsigned char)result;
}
// ChangeLightness() is a utility function that simply darkens
// or lightens a color, based on the specified percentage
// ialpha of 0 would be completely black, 100 completely white
// an ialpha of 100 returns the same colour
// static
void wxColourBase::ChangeLightness(unsigned char* r, unsigned char* g, unsigned char* b,
int ialpha)
{
if (ialpha == 100) return;
// ialpha is 0..200 where 0 is completely black
// and 200 is completely white and 100 is the same
// convert that to normal alpha 0.0 - 1.0
ialpha = wxMax(ialpha, 0);
ialpha = wxMin(ialpha, 200);
double alpha = ((double)(ialpha - 100.0))/100.0;
unsigned char bg;
if (ialpha > 100)
{
// blend with white
bg = 255;
alpha = 1.0 - alpha; // 0 = transparent fg; 1 = opaque fg
}
else
{
// blend with black
bg = 0;
alpha = 1.0 + alpha; // 0 = transparent fg; 1 = opaque fg
}
*r = AlphaBlend(*r, bg, alpha);
*g = AlphaBlend(*g, bg, alpha);
*b = AlphaBlend(*b, bg, alpha);
}
wxColour wxColourBase::ChangeLightness(int ialpha) const
{
wxByte r = Red();
wxByte g = Green();
wxByte b = Blue();
ChangeLightness(&r, &g, &b, ialpha);
return wxColour(r,g,b);
}
#if WXWIN_COMPATIBILITY_2_6 #if WXWIN_COMPATIBILITY_2_6
// static // static

View File

@@ -26,6 +26,7 @@
#include "wx/module.h" #include "wx/module.h"
#include "wx/palette.h" #include "wx/palette.h"
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/colour.h"
#endif #endif
#include "wx/filefn.h" #include "wx/filefn.h"
@@ -1436,7 +1437,12 @@ void wxImage::Replace( unsigned char r1, unsigned char g1, unsigned char b1,
} }
} }
wxImage wxImage::ConvertToGreyscale( double lr, double lg, double lb ) const wxImage wxImage::ConvertToGreyscale(void) const
{
return ConvertToGreyscale(0.299, 0.587, 0.114);
}
wxImage wxImage::ConvertToGreyscale(double weight_r, double weight_g, double weight_b) const
{ {
wxImage image; wxImage image;
@@ -1460,16 +1466,14 @@ wxImage wxImage::ConvertToGreyscale( double lr, double lg, double lb ) const
const long size = M_IMGDATA->m_width * M_IMGDATA->m_height; const long size = M_IMGDATA->m_width * M_IMGDATA->m_height;
for ( long i = 0; i < size; i++, src += 3, dest += 3 ) for ( long i = 0; i < size; i++, src += 3, dest += 3 )
{ {
memcpy(dest, src, 3);
// don't modify the mask // don't modify the mask
if ( hasMask && src[0] == maskRed && src[1] == maskGreen && src[2] == maskBlue ) if ( hasMask && src[0] == maskRed && src[1] == maskGreen && src[2] == maskBlue )
{ {
memcpy(dest, src, 3);
} }
else else
{ {
// calculate the luma wxColour::MakeGrey(dest + 0, dest + 1, dest + 2, weight_r, weight_g, weight_b);
double luma = (src[0] * lr + src[1] * lg + src[2] * lb) + 0.5;
dest[0] = dest[1] = dest[2] = static_cast<unsigned char>(luma);
} }
} }
@@ -1514,15 +1518,43 @@ wxImage wxImage::ConvertToMono( unsigned char r, unsigned char g, unsigned char
for ( long i = 0; i < size; i++, srcd += 3, tard += 3 ) for ( long i = 0; i < size; i++, srcd += 3, tard += 3 )
{ {
if (srcd[0] == r && srcd[1] == g && srcd[2] == b) bool on = (srcd[0] == r) && (srcd[1] == g) && (srcd[2] == b);
tard[0] = tard[1] = tard[2] = 255; wxColourBase::MakeMono(tard + 0, tard + 1, tard + 2, on);
else
tard[0] = tard[1] = tard[2] = 0;
} }
return image; return image;
} }
wxImage wxImage::ConvertToDisabled(unsigned char brightness) const
{
wxImage image = *this;
unsigned char mr = image.GetMaskRed();
unsigned char mg = image.GetMaskGreen();
unsigned char mb = image.GetMaskBlue();
int width = image.GetWidth();
int height = image.GetHeight();
bool has_mask = image.HasMask();
for (int y = height-1; y >= 0; --y)
{
for (int x = width-1; x >= 0; --x)
{
unsigned char* data = image.GetData() + (y*(width*3))+(x*3);
unsigned char* r = data;
unsigned char* g = data+1;
unsigned char* b = data+2;
if (has_mask && (*r == mr) && (*g == mg) && (*b == mb))
continue;
wxColour::MakeDisabled(r, g, b, brightness);
}
}
return image;
}
int wxImage::GetWidth() const int wxImage::GetWidth() const
{ {
wxCHECK_MSG( Ok(), 0, wxT("invalid image") ); wxCHECK_MSG( Ok(), 0, wxT("invalid image") );