]> git.saurik.com Git - wxWidgets.git/commitdiff
Added support for alpha channels in interpolated
authorRobert Roebling <robert@roebling.de>
Thu, 18 Nov 2004 14:01:45 +0000 (14:01 +0000)
committerRobert Roebling <robert@roebling.de>
Thu, 18 Nov 2004 14:01:45 +0000 (14:01 +0000)
    and non-interpolated image rotation.
  Added helper method for turning shades of grey
    into shades of alpha and a colour.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30604 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/image.h
src/common/image.cpp

index aa3070e60d983306f571c56c7c1f181e1eae0c33..845de80b5b45729beb8a28579ec764928bdef77b 100644 (file)
@@ -211,6 +211,18 @@ public:
     // otherwise:
     bool ConvertAlphaToMask(unsigned char threshold = 128);
 
     // otherwise:
     bool ConvertAlphaToMask(unsigned char threshold = 128);
 
+    // This method converts an image where the original alpha
+    // information is only available as a shades of a colour
+    // (actually shades of grey) typically when you draw anti-
+    // aliased text into a bitmap. The DC drawinf routines
+    // draw grey values on the black background although they
+    // actually mean to draw white with differnt alpha values.
+    // This method reverses it, assuming a black (!) background
+    // and white text (actually only the red channel is read). 
+    // The method will then fill up the whole image with the
+    // colour given.
+    bool ConvertColourToAlpha( unsigned char r, unsigned char g, unsigned char b ); 
+
     static bool CanRead( const wxString& name );
     static int GetImageCount( const wxString& name, long type = wxBITMAP_TYPE_ANY );
     virtual bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 );
     static bool CanRead( const wxString& name );
     static int GetImageCount( const wxString& name, long type = wxBITMAP_TYPE_ANY );
     virtual bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY, int index = -1 );
index afd54ca6365183fa74407c9cdf5b676abd5846d6..a86831b26b0dfa77e7542ffb3d8fb907ac3fef48 100644 (file)
@@ -804,6 +804,33 @@ unsigned char wxImage::GetAlpha(int x, int y) const
     return M_IMGDATA->m_alpha[y*w + x];
 }
 
     return M_IMGDATA->m_alpha[y*w + x];
 }
 
+bool wxImage::ConvertColourToAlpha( unsigned char r, unsigned char g, unsigned char b )
+{
+    SetAlpha( NULL );
+    
+    int w = M_IMGDATA->m_width,
+        h = M_IMGDATA->m_height;
+    
+    unsigned char *alpha = GetAlpha();
+    unsigned char *data = GetData();
+    
+    int x,y;
+    for (y = 0; y < h; y++)
+        for (x = 0; x < w; x++)
+            {
+                *alpha = *data;
+                alpha++;
+                *data = r;
+                data++;
+                *data = g;
+                data++;
+                *data = b;
+                data++;
+            }
+
+    return true;
+}
+
 void wxImage::SetAlpha( unsigned char *alpha )
 {
     wxCHECK_RET( Ok(), wxT("invalid image") );
 void wxImage::SetAlpha( unsigned char *alpha )
 {
     wxCHECK_RET( Ok(), wxT("invalid image") );
@@ -1668,15 +1695,25 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
 {
     int i;
     angle = -angle;     // screen coordinates are a mirror image of "real" coordinates
 {
     int i;
     angle = -angle;     // screen coordinates are a mirror image of "real" coordinates
+    
+    bool has_alpha = HasAlpha();
 
     // Create pointer-based array to accelerate access to wxImage's data
     unsigned char ** data = new unsigned char * [GetHeight()];
 
     // Create pointer-based array to accelerate access to wxImage's data
     unsigned char ** data = new unsigned char * [GetHeight()];
-
     data[0] = GetData();
     data[0] = GetData();
-
     for (i = 1; i < GetHeight(); i++)
         data[i] = data[i - 1] + (3 * GetWidth());
 
     for (i = 1; i < GetHeight(); i++)
         data[i] = data[i - 1] + (3 * GetWidth());
 
+    // Same for alpha channel    
+    unsigned char ** alpha = NULL;
+    if (has_alpha)
+    {
+        alpha = new unsigned char * [GetHeight()];
+        alpha[0] = GetAlpha();
+        for (i = 1; i < GetHeight(); i++)
+            alpha[i] = alpha[i - 1] + GetWidth();
+    }
+
     // precompute coefficients for rotation formula
     // (sine and cosine of the angle)
     const double cos_angle = cos(angle);
     // precompute coefficients for rotation formula
     // (sine and cosine of the angle)
     const double cos_angle = cos(angle);
@@ -1698,7 +1735,11 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
     int x2 = (int) ceil (wxMax (wxMax(p1.x, p2.x), wxMax(p3.x, p4.x)));
     int y2 = (int) ceil (wxMax (wxMax(p1.y, p2.y), wxMax(p3.y, p4.y)));
 
     int x2 = (int) ceil (wxMax (wxMax(p1.x, p2.x), wxMax(p3.x, p4.x)));
     int y2 = (int) ceil (wxMax (wxMax(p1.y, p2.y), wxMax(p3.y, p4.y)));
 
+    // Create rotated image
     wxImage rotated (x2 - x1 + 1, y2 - y1 + 1, false);
     wxImage rotated (x2 - x1 + 1, y2 - y1 + 1, false);
+    // With alpha channel
+    if (has_alpha)
+        rotated.SetAlpha();
 
     if (offset_after_rotation != NULL)
     {
 
     if (offset_after_rotation != NULL)
     {
@@ -1710,6 +1751,10 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
     //      array here (and in fact it would be slower).
     //
     unsigned char * dst = rotated.GetData();
     //      array here (and in fact it would be slower).
     //
     unsigned char * dst = rotated.GetData();
+    
+    unsigned char * alpha_dst = NULL;
+    if (has_alpha)
+        alpha_dst = rotated.GetAlpha();
 
     // GRG: if the original image has a mask, use its RGB values
     //      as the blank pixel, else, fall back to default (black).
 
     // GRG: if the original image has a mask, use its RGB values
     //      as the blank pixel, else, fall back to default (black).
@@ -1796,28 +1841,52 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                         unsigned char *p = data[y1] + (3 * x1);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
                         unsigned char *p = data[y1] + (3 * x1);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
-                        *(dst++) = *(p++);
+                        *(dst++) = *p;
+                        
+                        if (has_alpha)
+                        {
+                            unsigned char *p = alpha[y1] + x1;
+                            *(alpha_dst++) = *p;
+                        }
                     }
                     else if (d2 < gs_Epsilon)
                     {
                         unsigned char *p = data[y1] + (3 * x2);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
                     }
                     else if (d2 < gs_Epsilon)
                     {
                         unsigned char *p = data[y1] + (3 * x2);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
-                        *(dst++) = *(p++);
+                        *(dst++) = *p;
+                        
+                        if (has_alpha)
+                        {
+                            unsigned char *p = alpha[y1] + x2;
+                            *(alpha_dst++) = *p;
+                        }
                     }
                     else if (d3 < gs_Epsilon)
                     {
                         unsigned char *p = data[y2] + (3 * x2);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
                     }
                     else if (d3 < gs_Epsilon)
                     {
                         unsigned char *p = data[y2] + (3 * x2);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
-                        *(dst++) = *(p++);
+                        *(dst++) = *p;
+                        
+                        if (has_alpha)
+                        {
+                            unsigned char *p = alpha[y2] + x2;
+                            *(alpha_dst++) = *p;
+                        }
                     }
                     else if (d4 < gs_Epsilon)
                     {
                         unsigned char *p = data[y2] + (3 * x1);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
                     }
                     else if (d4 < gs_Epsilon)
                     {
                         unsigned char *p = data[y2] + (3 * x1);
                         *(dst++) = *(p++);
                         *(dst++) = *(p++);
-                        *(dst++) = *(p++);
+                        *(dst++) = *p;
+                        
+                        if (has_alpha)
+                        {
+                            unsigned char *p = alpha[y2] + x1;
+                            *(alpha_dst++) = *p;
+                        }
                     }
                     else
                     {
                     }
                     else
                     {
@@ -1843,6 +1912,19 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                             ( (w1 * *v1 + w2 * *v2 +
                                w3 * *v3 + w4 * *v4) /
                               (w1 + w2 + w3 + w4) );
                             ( (w1 * *v1 + w2 * *v2 +
                                w3 * *v3 + w4 * *v4) /
                               (w1 + w2 + w3 + w4) );
+                              
+                        if (has_alpha)
+                        {
+                            unsigned char *v1 = alpha[y1] + (x1);
+                            unsigned char *v2 = alpha[y1] + (x2);
+                            unsigned char *v3 = alpha[y2] + (x2);
+                            unsigned char *v4 = alpha[y2] + (x1);
+
+                            *(alpha_dst++) = (unsigned char)
+                                ( (w1 * *v1 + w2 * *v2 +
+                                   w3 * *v3 + w4 * *v4) /
+                                  (w1 + w2 + w3 + w4) );
+                        }
                     }
                 }
                 else
                     }
                 }
                 else
@@ -1850,6 +1932,9 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                     *(dst++) = blank_r;
                     *(dst++) = blank_g;
                     *(dst++) = blank_b;
                     *(dst++) = blank_r;
                     *(dst++) = blank_g;
                     *(dst++) = blank_b;
+                   
+                    if (has_alpha)
+                        *(alpha_dst++) = 0;
                 }
             }
         }
                 }
             }
         }
@@ -1872,18 +1957,30 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i
                     *(dst++) = *(p++);
                     *(dst++) = *(p++);
                     *(dst++) = *p;
                     *(dst++) = *(p++);
                     *(dst++) = *(p++);
                     *(dst++) = *p;
+                    
+                    if (has_alpha)
+                    {
+                        unsigned char *p = alpha[ys] + (xs);
+                        *(alpha_dst++) = *p;
+                    }
                 }
                 else
                 {
                     *(dst++) = blank_r;
                     *(dst++) = blank_g;
                     *(dst++) = blank_b;
                 }
                 else
                 {
                     *(dst++) = blank_r;
                     *(dst++) = blank_g;
                     *(dst++) = blank_b;
+                    
+                    if (has_alpha)
+                        *(alpha_dst++) = 255;
                 }
             }
         }
     }
 
     delete [] data;
                 }
             }
         }
     }
 
     delete [] data;
+    
+    if (has_alpha)
+        delete [] alpha;
 
     return rotated;
 }
 
     return rotated;
 }