]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/_image.i
fixed deadlock when calling wxPostEvent() from worker thread
[wxWidgets.git] / wxPython / src / _image.i
index bd2576c137f0e2417b9904a1c32c6777c111a8ba..6b315bc824b97d15b8f1d24a5d09f40df220273d 100644 (file)
@@ -28,6 +28,13 @@ enum {
 };
 
 
+// Constants for wxImage::Scale() for determining the level of quality
+enum
+{
+    wxIMAGE_QUALITY_NORMAL = 0,
+    wxIMAGE_QUALITY_HIGH = 1
+};
+
 //---------------------------------------------------------------------------
 %newgroup
 
@@ -46,19 +53,61 @@ public:
     //bool LoadFile(wxImage* image, wxInputStream& stream);
     //bool SaveFile(wxImage* image, wxOutputStream& stream);
     //virtual int GetImageCount( wxInputStream& stream );
-    //bool CanRead( wxInputStream& stream );
 
     bool CanRead( const wxString& name );
-
+    %Rename(CanReadStream, bool, CanRead( wxInputStream& stream ));
+    
     void SetName(const wxString& name);
     void SetExtension(const wxString& extension);
     void SetType(long type);
     void SetMimeType(const wxString& mimetype);
+
+    %property(Extension, GetExtension, SetExtension, doc="See `GetExtension` and `SetExtension`");
+    %property(MimeType, GetMimeType, SetMimeType, doc="See `GetMimeType` and `SetMimeType`");
+    %property(Name, GetName, SetName, doc="See `GetName` and `SetName`");
+    %property(Type, GetType, SetType, doc="See `GetType` and `SetType`");
+};
+
+
+//---------------------------------------------------------------------------
+
+
+DocStr(wxPyImageHandler,
+"This is the base class for implementing image file loading/saving, and
+image creation from data, all written in Python.  To create a custom
+image handler derive a new class from wx.PyImageHandler and provide
+the following methods::
+
+    def DoCanRead(self, stream) --> bool
+        '''Check if this handler can read the image on the stream'''
+
+    def LoadFile(self, image, stream, verbose, index) --> bool
+        '''Load image data from the stream and load it into image.'''
+
+    def SaveFile(self, image, stream, verbose) --> bool
+        '''Save the iamge data in image to the stream using
+           this handler's image file format.'''
+
+    def GetImageCount(self, stream) --> int
+        '''If this image format can hold more than one image,
+           how many does the image on the stream have?'''
+
+To activate your handler create an instance of it and pass it to
+`wx.Image_AddHandler`.  Be sure to call `SetName`, `SetType`, and
+`SetExtension` from your constructor.
+", "");
+
+class wxPyImageHandler: public wxImageHandler {
+public:
+    %pythonAppend wxPyImageHandler() "self._SetSelf(self)"
+    wxPyImageHandler();
+    void _SetSelf(PyObject *self);
 };
 
 
 //---------------------------------------------------------------------------
 
+
 class wxImageHistogram /* : public wxImageHistogramBase */
 {
 public:
@@ -116,19 +165,6 @@ key value from a RGB tripple.", "");
 
 //---------------------------------------------------------------------------
 
-%{
-    typedef unsigned char* buffer;
-%}    
-
-%typemap(in) (buffer data, int DATASIZE)
-    { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
-
-%typemap(in) (buffer alpha, int ALPHASIZE)
-    { if (!PyArg_Parse($input, "t#", &$1, &$2)) SWIG_fail; }
-
-//---------------------------------------------------------------------------
-
-
 DocStr(wxImage,
 "A platform-independent image class.  An image can be created from
 data, or using `wx.Bitmap.ConvertToImage`, or loaded from a file in a
@@ -155,6 +191,48 @@ Unlike RGB data, not all images have an alpha channel and before using
 with `HasAlpha`. Note that currently only images loaded from PNG files
 with transparency information will have an alpha channel.", "");
 
+
+%{
+// Pull the nested class out to the top level for SWIG's sake
+#define wxImage_RGBValue wxImage::RGBValue
+#define wxImage_HSVValue wxImage::HSVValue
+%}
+
+DocStr(wxImage_RGBValue,
+"An object that contains values for red, green and blue which represent
+the value of a color. It is used by `wx.Image.HSVtoRGB` and
+`wx.Image.RGBtoHSV`, which converts between HSV color space and RGB
+color space.", "");       
+class wxImage_RGBValue
+{
+public:
+    DocCtorStr(
+        wxImage_RGBValue(byte r=0, byte g=0, byte b=0),
+        "Constructor.", "");
+    byte red;  
+    byte green;
+    byte blue;
+};
+
+
+DocStr(wxImage_HSVValue,
+"An object that contains values for hue, saturation and value which
+represent the value of a color.  It is used by `wx.Image.HSVtoRGB` and
+`wx.Image.RGBtoHSV`, which +converts between HSV color space and RGB
+color space.", "");
+class wxImage_HSVValue
+{
+public:
+    DocCtorStr(
+        wxImage_HSVValue(double h=0.0, double s=0.0, double v=0.0),
+        "Constructor.", "");
+    double hue;  
+    double saturation;
+    double value;
+};
+
+
+
 class wxImage : public wxObject {
 public:
     %typemap(out) wxImage*;    // turn off this typemap
@@ -190,8 +268,8 @@ public:
         largest and most colourful one by the ICO handler.
 
 :see: `wx.ImageFromMime`, `wx.ImageFromStream`, `wx.ImageFromStreamMime`,
-      `wx.EmptyImage`, `wx.ImageFromBitmap`, `wx.ImageFromData`,
-      `wx.ImageFromDataWithAlpha`
+      `wx.EmptyImage`, `wx.ImageFromBitmap`, `wx.ImageFromBuffer`,
+      `wx.ImageFromData`, `wx.ImageFromDataWithAlpha`
 ");
     
     ~wxImage();
@@ -314,7 +392,7 @@ alpha data must be width*height bytes.", "
 
     // TODO: wxImage( char** xpmData );
 
-    // Turn it back on again
+    // Turn the typemap back on again
     %typemap(out) wxImage* { $result = wxPyMake_wxObject($1, $owner); }
 
 
@@ -329,19 +407,60 @@ initialized to black. Otherwise, the image data will be uninitialized.", "");
     
 
     DocDeclStr(
-        wxImage , Scale( int width, int height ),
+        wxImage , Scale( int width, int height, int quality = wxIMAGE_QUALITY_NORMAL ),
         "Returns a scaled version of the image. This is also useful for scaling
 bitmaps in general as the only other way to scale bitmaps is to blit a
-`wx.MemoryDC` into another `wx.MemoryDC`.", "
+`wx.MemoryDC` into another `wx.MemoryDC`.  The ``quality`` parameter
+specifies what method to use for resampling the image.  It can be
+either wx.IMAGE_QUALITY_NORMAL, which uses the normal default scaling
+method of pixel replication, or wx.IMAGE_QUALITY_HIGH which uses
+bicubic and box averaging resampling methods for upsampling and
+downsampling respectively.", "
+
+It should be noted that although using wx.IMAGE_QUALITY_HIGH produces
+much nicer looking results it is a slower method.  Downsampling will
+use the box averaging method which seems to operate very fast.  If you
+are upsampling larger images using this method you will most likely
+notice that it is a bit slower and in extreme cases it will be quite
+substantially slower as the bicubic algorithm has to process a lot of
+data.
+
+It should also be noted that the high quality scaling may not work as
+expected when using a single mask colour for transparency, as the
+scaling will blur the image and will therefore remove the mask
+partially. Using the alpha channel will work.
 
 :see: `Rescale`");
+
+    
+    wxImage ResampleBox(int width, int height) const;
+    wxImage ResampleBicubic(int width, int height) const;
+
+    DocDeclStr(
+        wxImage , Blur(int radius),
+        "Blurs the image in both horizontal and vertical directions by the
+specified pixel ``radius``. This should not be used when using a
+single mask colour for transparency.", "");
+    
+    DocDeclStr(
+        wxImage , BlurHorizontal(int radius),
+        "Blurs the image in the horizontal direction only. This should not be
+used when using a single mask colour for transparency.
+", "");
+    
+    DocDeclStr(
+        wxImage , BlurVertical(int radius),
+        "Blurs the image in the vertical direction only. This should not be
+used when using a single mask colour for transparency.", "");
+    
+
     
     DocDeclStr(
         wxImage , ShrinkBy( int xFactor , int yFactor ) const ,
         "Return a version of the image scaled smaller by the given factors.", "");
     
     DocDeclStr(
-        wxImage& , Rescale(int width, int height),
+        wxImage& , Rescale(int width, int height, int quality = wxIMAGE_QUALITY_NORMAL),
         "Changes the size of the image in-place by scaling it: after a call to
 this function, the image will have the given width and height.
 
@@ -550,8 +669,9 @@ object, using a MIME type string to specify the image file format.", "",
     
 
     DocDeclStr(
-        bool , Ok(),
+        bool , IsOk(),
         "Returns true if image data is present.", "");
+    %pythoncode { Ok = IsOk }
     
     DocDeclStr(
         int , GetWidth(),
@@ -701,7 +821,7 @@ data must be width*height.", "");
 
 
         
-        DocStr(GetDataBuffer,
+        DocStr(GetAlphaBuffer,
                "Returns a writable Python buffer object that is pointing at the Alpha
 data buffer inside the wx.Image. You need to ensure that you do not
 use this buffer object after the image has been destroyed.", "");
@@ -715,7 +835,7 @@ use this buffer object after the image has been destroyed.", "");
         }
 
         
-        DocStr(SetDataBuffer,
+        DocStr(SetAlphaBuffer,
                "Sets the internal image alpha pointer to point at a Python buffer
 object.  This can save making an extra copy of the data but you must
 ensure that the buffer object lives as long as the wx.Image does.", "");
@@ -794,6 +914,14 @@ indicates the orientation.", "");
                         byte r2, byte g2, byte b2 ),
         "Replaces the colour specified by ``(r1,g1,b1)`` by the colour
 ``(r2,g2,b2)``.", "");
+
+    DocDeclStr(
+        wxImage , ConvertToGreyscale( double lr = 0.299,
+                                      double lg = 0.587,
+                                      double lb = 0.114 ) const,
+        "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", "");
     
 
     DocDeclStr(
@@ -809,7 +937,7 @@ colour everywhere else.", "");
 JPEG file, the option ``wx.IMAGE_OPTION_QUALITY`` is used, which is a
 number between 0 and 100 (0 is terrible, 100 is very good).", "
 
-    =================================
+    ================================= ===
     wx.IMAGE_OPTION_BMP_FORMAT
     wx.IMAGE_OPTION_CUR_HOTSPOT_X
     wx.IMAGE_OPTION_CUR_HOTSPOT_Y
@@ -824,7 +952,7 @@ number between 0 and 100 (0 is terrible, 100 is very good).", "
     wx.IMAGE_OPTION_IMAGEDESCRIPTOR
     wx.IMAGE_OPTION_PNG_FORMAT
     wx.IMAGE_OPTION_PNG_BITDEPTH
-    =================================
+    ================================= ===
 
 :see: `HasOption`, `GetOption`, `GetOptionInt`, `SetOptionInt`");
     
@@ -861,6 +989,12 @@ option is not present, the function returns 0.", "
     static void AddHandler( wxImageHandler *handler );
     static void InsertHandler( wxImageHandler *handler );
     static bool RemoveHandler( const wxString& name );
+    %extend {
+        static PyObject* GetHandlers() {
+            wxList& list = wxImage::GetHandlers();
+            return wxPy_ConvertList(&list);
+        }
+    }
     
     DocDeclStr(
         static wxString , GetImageExtWildcard(),
@@ -888,11 +1022,96 @@ MustHaveApp(ConvertToMonoBitmap);
         }
     }
 
-    %pythoncode { def __nonzero__(self): return self.Ok() }
+    
+    DocDeclStr(
+        void , RotateHue(double angle),
+        "Rotates the hue of each pixel of the image. Hue is a double in the
+range -1.0..1.0 where -1.0 is -360 degrees and 1.0 is 360 degrees", "");
+        
+    DocDeclStr(
+        static wxImage_HSVValue , RGBtoHSV(wxImage_RGBValue rgb),
+        "Converts a color in RGB color space to HSV color space.", "");
+    
+    DocDeclStr(
+        static wxImage_RGBValue , HSVtoRGB(wxImage_HSVValue hsv),
+        "Converts a color in HSV color space to RGB color space.", "");
+    
+
+    %pythoncode { def __nonzero__(self): return self.IsOk() }
+    
+    %property(AlphaBuffer, GetAlphaBuffer, SetAlphaBuffer, doc="See `GetAlphaBuffer` and `SetAlphaBuffer`");
+    %property(AlphaData, GetAlphaData, SetAlphaData, doc="See `GetAlphaData` and `SetAlphaData`");
+    %property(Data, GetData, SetData, doc="See `GetData` and `SetData`");
+    %property(DataBuffer, GetDataBuffer, SetDataBuffer, doc="See `GetDataBuffer` and `SetDataBuffer`");
+    %property(Height, GetHeight, doc="See `GetHeight`");
+    %property(MaskBlue, GetMaskBlue, doc="See `GetMaskBlue`");
+    %property(MaskGreen, GetMaskGreen, doc="See `GetMaskGreen`");
+    %property(MaskRed, GetMaskRed, doc="See `GetMaskRed`");
+    %property(Width, GetWidth, doc="See `GetWidth`");
+    
 };
 
 
 
+// Make an image from buffer objects.  Not that this is here instead of in the
+// wxImage class (as a constructor) because there is already another one with
+// the exact same signature, so there woudl be ambiguities in the generated
+// C++.  Doing it as an independent factory function like this accomplishes
+// the same thing however.
+%newobject _ImageFromBuffer;
+%inline %{
+    wxImage* _ImageFromBuffer(int width, int height,
+                              buffer data, int DATASIZE,
+                              buffer alpha=NULL, int ALPHASIZE=0)
+    {
+        if (DATASIZE != width*height*3) {
+            wxPyErr_SetString(PyExc_ValueError, "Invalid data buffer size.");
+            return NULL;
+        }
+        if (alpha != NULL) {
+            if (ALPHASIZE != width*height) {
+                wxPyErr_SetString(PyExc_ValueError, "Invalid alpha buffer size.");
+                return NULL;
+            }
+            return new wxImage(width, height, data, alpha, true);
+        }                
+        return new wxImage(width, height, data, true);
+    }                              
+%}
+
+%pythoncode {
+def ImageFromBuffer(width, height, dataBuffer, alphaBuffer=None):
+    """
+    Creates a `wx.Image` from the data in dataBuffer.  The dataBuffer
+    parameter must be a Python object that implements the buffer interface,
+    such as a string, array, etc.  The dataBuffer object is expected to
+    contain a series of RGB bytes and be width*height*3 bytes long.  A buffer
+    object can optionally be supplied for the image's alpha channel data, and
+    it is expected to be width*height bytes long.
+
+    The wx.Image will be created with its data and alpha pointers initialized
+    to the memory address pointed to by the buffer objects, thus saving the
+    time needed to copy the image data from the buffer object to the wx.Image.
+    While this has advantages, it also has the shoot-yourself-in-the-foot
+    risks associated with sharing a C pointer between two objects.
+
+    To help alleviate the risk a reference to the data and alpha buffer
+    objects are kept with the wx.Image, so that they won't get deleted until
+    after the wx.Image is deleted.  However please be aware that it is not
+    guaranteed that an object won't move its memory buffer to a new location
+    when it needs to resize its contents.  If that happens then the wx.Image
+    will end up referring to an invalid memory location and could cause the
+    application to crash.  Therefore care should be taken to not manipulate
+    the objects used for the data and alpha buffers in a way that would cause
+    them to change size.
+    """
+    image = _core_._ImageFromBuffer(width, height, dataBuffer, alphaBuffer)
+    image._buffer = dataBuffer
+    image._alpha = alphaBuffer
+    return image
+}
+
+
 ///void wxInitAllImageHandlers();
 
 %pythoncode {
@@ -906,7 +1125,6 @@ MustHaveApp(ConvertToMonoBitmap);
 
 
 
-// See also wxPy_ReinitStockObjects in helpers.cpp
 %immutable;
 const wxImage    wxNullImage;
 %mutable;
@@ -1045,7 +1263,12 @@ public:
 };
 
 
-#if wxUSE_IFF
+
+#if 0
+%{
+#include <wx/imagiff.h>
+%}
+
 DocStr(wxIFFHandler,
 "A `wx.ImageHandler` for IFF image files.", "");
 class wxIFFHandler : public wxImageHandler {
@@ -1054,6 +1277,19 @@ public:
 };
 #endif
 
+
+%{
+#include <wx/imagtga.h>
+%}
+
+DocStr(wxTGAHandler,
+"A `wx.ImageHandler` for TGA image files.", "");
+class wxTGAHandler : public wxImageHandler {
+public:
+    wxTGAHandler();
+};
+
+
 //---------------------------------------------------------------------------
 
 %{