]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied part of #10034: wxImage::ConvertToDisabled()
authorJulian Smart <julian@anthemion.co.uk>
Thu, 24 Sep 2009 20:05:33 +0000 (20:05 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Thu, 24 Sep 2009 20:05:33 +0000 (20:05 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62099 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/bitmap.h
include/wx/colour.h
include/wx/image.h
interface/wx/bitmap.h
interface/wx/colour.h
interface/wx/icon.h
interface/wx/image.h
src/common/bmpbase.cpp
src/common/colourcmn.cpp
src/common/image.cpp

index e6e837d94830272ff3e33fdb48ccc0b0234c3027..a287777b686df1011fe5179df2474b0eaa9b10ff 100644 (file)
@@ -175,6 +175,9 @@ public:
 
     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,
                           const wxPalette *palette = NULL) const = 0;
     virtual bool LoadFile(const wxString &name, wxBitmapType type) = 0;
index 6c731ef546bd04b83947cea6e402bc4f011c6865..f2ca87a8772ed7e534ec76c437ccf6dd34b076c4 100644 (file)
@@ -15,7 +15,6 @@
 #include "wx/defs.h"
 #include "wx/gdiobj.h"
 
-
 class WXDLLIMPEXP_FWD_CORE wxColour;
 
 // A macro to define the standard wxColour constructors:
@@ -148,6 +147,22 @@ public:
     bool Ok() const { return IsOk(); }
 #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
     // ---------------
 
index eb0d19b7db11608bc6e5774d252cd61f40c505cb..e0e05f67e2c2b0b59e927bfaf1f2e20c7a6119fe 100644 (file)
@@ -354,13 +354,17 @@ public:
                   unsigned char r2, unsigned char g2, unsigned char b2 );
 
     // 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
-    wxImage ConvertToGreyscale( double lr = 0.299, double lg = 0.587, double lb = 0.114 ) const;
+    // 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 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,
     // everything else by black)
     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
     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 );
index 1d2b8b81f8e1534ea19af93dcfd03a1a6796ed80..913d530e9e42fa546cc655c5cbd1d760c455bacf 100644 (file)
@@ -498,6 +498,12 @@ public:
     */
     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.
 
index d6f3fa5f828f35f43d9792dce25c861667a2419f..82134dd1fb1bf38f3bd2c6cd8c19cfd3016564ec 100644 (file)
@@ -213,6 +213,54 @@ public:
         colours and alpha values.
     */
     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;
 };
 
 
index 5a055a7168e75fd1a5755a8ee1c4989b03edb9be..9cb95d73482bf2575b5620ff7287a1954c38368e 100644 (file)
@@ -171,6 +171,12 @@ public:
     */
     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.
         Under MS Windows the bitmap must have mask colour set.
index 1b44387d2af8727a70e7cb24a82be98799fbd1bd..43dcf59028a67b3b92150e770d96518de25364be 100644 (file)
@@ -109,23 +109,23 @@ public:
     /**
         Returns @true if this handler supports the image format contained in the
         given stream.
-        
+
         This function doesn't modify the current stream position (because it
         restores the original position before returning; this however requires the
         stream to be seekable; see wxStreamBase::IsSeekable).
     */
-    bool CanRead( wxInputStream& stream );    
+    bool CanRead( wxInputStream& stream );
 
     /**
         Returns @true if this handler supports the image format contained in the
         file with the given name.
-        
+
         This function doesn't modify the current stream position (because it
         restores the original position before returning; this however requires the
         stream to be seekable; see wxStreamBase::IsSeekable).
     */
     bool CanRead( const wxString& filename );
-    
+
     /**
         Gets the preferred file extension associated with this handler.
 
@@ -348,7 +348,7 @@ class wxImage : public wxObject
 {
 public:
     /**
-        A simple class which stores red, green and blue values as 8 bit unsigned integers 
+        A simple class which stores red, green and blue values as 8 bit unsigned integers
         in the range of 0-255.
     */
     class RGBValue
@@ -398,7 +398,7 @@ public:
             If @true, initialize the image to black.
     */
     wxImage(int width, int height, bool clear = true);
-    
+
     /**
         @overload
     */
@@ -425,7 +425,7 @@ public:
         @overload
     */
     wxImage(const wxSize& sz, unsigned char* data, bool static_data = false);
-    
+
     /**
         Creates an image from data in memory. If @a static_data is @false
         then the wxImage will take ownership of the data and free it
@@ -451,7 +451,7 @@ public:
     */
     wxImage(const wxSize& sz, unsigned char* data, unsigned char* data, unsigned char* alpha,
             bool static_data = false);
-    
+
     /**
         Creates an image from XPM data.
 
@@ -549,13 +549,13 @@ public:
     */
     virtual ~wxImage();
 
-    
-    
+
+
     /**
         @name Image creation, initialization and deletion functions
     */
     //@{
-    
+
     /**
         Returns an identical copy of this image.
     */
@@ -577,7 +577,7 @@ public:
     /**
         Creates a fresh image.
         See wxImage::wxImage(int,int,unsigned char*,bool) for more info.
-        
+
         @return @true if the call succeeded, @false otherwise.
     */
     bool Create( int width, int height, unsigned char* data, bool static_data = false );
@@ -590,16 +590,16 @@ public:
     /**
         Creates a fresh image.
         See wxImage::wxImage(int,int,unsigned char*,unsigned char*,bool) for more info.
-        
+
         @return @true if the call succeeded, @false otherwise.
     */
     bool Create( int width, int height, unsigned char* data, unsigned char* alpha, bool static_data = false );
-    
+
     /**
         @overload
     */
     bool Create( const wxSize& sz, unsigned char* data, unsigned char* alpha, bool static_data = false );
-        
+
     /**
         Initialize the image data with zeroes (the default) or with the
         byte value given as @a value.
@@ -612,7 +612,7 @@ public:
         Destroys the image data.
     */
     void Destroy();
-    
+
     /**
         Initializes the image alpha channel data.
 
@@ -773,7 +773,7 @@ public:
     */
     wxImage Scale(int width, int height,
                    wxImageResizeQuality quality = wxIMAGE_QUALITY_NORMAL) const;
-    
+
     /**
         Returns a resized version of this image without scaling it by adding either a
         border with the given colour or cropping as necessary.
@@ -847,9 +847,15 @@ public:
         The returned image uses the luminance component of the original to
         calculate the greyscale. Defaults to using the standard ITU-T BT.601
         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 weight_r, double weight_g, double weight_b) const;
+
+    /**
+        Returns a greyscale version of the image.
+        @since 2.9.0
     */
-    wxImage ConvertToGreyscale(double lr = 0.299, double lg = 0.587, double lb = 1.114) const;
+    wxImage ConvertToGreyscale() const;
 
     /**
         Returns monochromatic version of the image.
@@ -858,15 +864,21 @@ public:
         colour and black colour everywhere else.
     */
     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;
+
     //@}
-    
-    
+
+
     /**
         @name Miscellaneous functions
     */
     //@{
-    
+
     /**
         Computes the histogram of the image. @a histogram is a reference to
         wxImageHistogram object. wxImageHistogram is a specialization of
@@ -889,7 +901,7 @@ public:
         @return Returns number of colours in the histogram.
     */
     unsigned long ComputeHistogram(wxImageHistogram& histogram) const;
-    
+
     /**
         Finds the first colour that is never used in the image.
         The search begins at given initial colour and continues by increasing
@@ -922,10 +934,10 @@ public:
         @return Returns 'this' object.
     */
     wxImage& operator=(const wxImage& image);
-    
+
     //@}
-    
-    
+
+
     /**
         @name Getters
     */
@@ -1011,7 +1023,7 @@ public:
         @see GetHeight(), GetWidth()
     */
     wxSize GetSize() const;
-    
+
     /**
         Gets a user-defined string-valued option.
 
@@ -1390,12 +1402,12 @@ public:
         The data must have been allocated with @c malloc(), @b NOT with
         @c operator new.
 
-        If @a static_data is @false, after this call the pointer to the data is 
+        If @a static_data is @false, after this call the pointer to the data is
         owned by the wxImage object, that will be responsible for deleting it.
         Do not pass to this function a pointer obtained through GetData().
     */
     void SetData(unsigned char* data, bool static_data = false);
-    
+
     /**
         @overload
     */
@@ -1453,8 +1465,8 @@ public:
         @see GetOption(), GetOptionInt(), HasOption()
     */
     void SetOption(const wxString& name, const wxString& value);
-    
-    /** 
+
+    /**
         @overload
     */
     void SetOption(const wxString& name, int value);
@@ -1498,14 +1510,14 @@ public:
     void SetType(wxBitmapType type);
 
     //@}
-    
-    
-    
+
+
+
     /**
         @name Handler management functions
     */
     //@{
-    
+
     /**
         Register an image handler.
         See @ref image_handlers for a list of the available handlers.
@@ -1517,7 +1529,7 @@ public:
         This function is called by wxWidgets on exit.
     */
     static void CleanUpHandlers();
-    
+
     /**
         Finds the handler with the given name.
 
@@ -1610,22 +1622,22 @@ public:
         @see wxImageHandler
     */
     static bool RemoveHandler(const wxString& name);
-    
+
     //@}
-    
-    
+
+
     /**
-        Returns @true if at least one of the available image handlers can read 
+        Returns @true if at least one of the available image handlers can read
         the file with the given name.
-        
+
         See wxImageHandler::CanRead for more info.
     */
     static bool CanRead(const wxString& filename);
-    
+
     /**
-        Returns @true if at least one of the available image handlers can read 
+        Returns @true if at least one of the available image handlers can read
         the data in the given stream.
-        
+
         See wxImageHandler::CanRead for more info.
     */
     static bool CanRead(wxInputStream& stream);
@@ -1640,7 +1652,7 @@ public:
         of the file to query.
         For the overload taking the parameter @a stream, that's the opened input
         stream with image data.
-        
+
         See wxImageHandler::GetImageCount() for more info.
 
         The parameter @a type may be one of the following values:
@@ -1686,12 +1698,12 @@ public:
         @see wxImageHandler
     */
     static wxString GetImageExtWildcard();
-    
+
     /**
         Converts a color in RGB color space to HSV color space.
     */
     static wxImage::HSVValue RGBtoHSV(const wxImage::RGBValue& rgb);
-    
+
     /**
         Converts a color in HSV color space to RGB color space.
     */
@@ -1714,7 +1726,7 @@ wxImage wxNullImage;
 /**
     Initializes all available image handlers. For a list of available handlers,
     see wxImage.
-    If you don't need/want all image handlers loaded 
+    If you don't need/want all image handlers loaded
 
     @see wxImage, wxImageHandler
 
index e80091dada39aff4f0887733d31510d4c6c4774b..eebf56e5f93bfac760cafd99f26033f82e7db3cb 100644 (file)
@@ -135,6 +135,16 @@ public:
     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)
 
 #endif // wxUSE_BITMAP_BASE
index 8fa9c927c213cbaf06c1d0ad46296bbeccef9600..943ceb5683d91ce7c8b4601e697e21a14bf5f3b3 100644 (file)
@@ -149,6 +149,97 @@ wxString wxColourBase::GetAsString(long flags) const
     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
 
 // static
index e13640c4d65378b14ccca15da3d0cff95545fe4c..a3c94837675046e78b17694e0121b7dfc65a3628 100644 (file)
@@ -26,6 +26,7 @@
     #include "wx/module.h"
     #include "wx/palette.h"
     #include "wx/intl.h"
+    #include "wx/colour.h"
 #endif
 
 #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;
 
@@ -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;
     for ( long i = 0; i < size; i++, src += 3, dest += 3 )
     {
+        memcpy(dest, src, 3);
         // don't modify the mask
         if ( hasMask && src[0] == maskRed && src[1] == maskGreen && src[2] == maskBlue )
         {
-            memcpy(dest, src, 3);
         }
         else
         {
-            // calculate the luma
-            double luma = (src[0] * lr + src[1] * lg + src[2] * lb) + 0.5;
-            dest[0] = dest[1] = dest[2] = static_cast<unsigned char>(luma);
+            wxColour::MakeGrey(dest + 0, dest + 1, dest + 2, weight_r, weight_g, weight_b);
         }
     }
 
@@ -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 )
     {
-        if (srcd[0] == r && srcd[1] == g && srcd[2] == b)
-            tard[0] = tard[1] = tard[2] = 255;
-        else
-            tard[0] = tard[1] = tard[2] = 0;
+        bool on = (srcd[0] == r) && (srcd[1] == g) && (srcd[2] == b);
+        wxColourBase::MakeMono(tard + 0, tard + 1, tard + 2, on);
     }
 
     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
 {
     wxCHECK_MSG( Ok(), 0, wxT("invalid image") );