mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 11:30:06 +01:00
Add Classic's enhancements to image and add unittests. Still need to add buffer and stream support.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@69418 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
175
etg/image.py
175
etg/image.py
@@ -1,6 +1,7 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/image.py
|
||||
# Author: Kevin Ollivier
|
||||
# Robin Dunn
|
||||
#
|
||||
# Created: 25-Aug-2011
|
||||
# Copyright: (c) 2011 by Wide Open Technologies
|
||||
@@ -17,8 +18,11 @@ DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = [ 'wxImage', 'wxImageHistogram' ]
|
||||
|
||||
ITEMS = [ 'wxImage',
|
||||
'wxImageHistogram',
|
||||
#'wxImageHandler', # TODO
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def run():
|
||||
@@ -31,16 +35,22 @@ def run():
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
c = module.find('wxImage')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
c.find('wxImage').findOverload('(const char *const *xpmData)').ignore()
|
||||
c.find('GetHandlers').ignore()
|
||||
|
||||
c.find('GetHandlers').ignore()
|
||||
c.find('AddHandler').ignore()
|
||||
c.find('InsertHandler').ignore()
|
||||
c.find('RemoveHandler').ignore()
|
||||
for m in c.find('FindHandler').all():
|
||||
m.ignore()
|
||||
c.find('FindHandlerMime').ignore()
|
||||
|
||||
|
||||
# TODO: Port the ctors and methods that deal with data buffers for getting
|
||||
# and setting the image and alpha data.
|
||||
|
||||
# TODO: Add these later when return types are defined.
|
||||
c.find('RGBtoHSV').ignore()
|
||||
c.find('HSVtoRGB').ignore()
|
||||
|
||||
|
||||
def setParamsPyInt(name):
|
||||
"""Set the pyInt flag on 'unsigned char' params"""
|
||||
method = c.find(name)
|
||||
@@ -59,7 +69,7 @@ def run():
|
||||
setParamsPyInt('SetMaskFromImage')
|
||||
setParamsPyInt('SetRGB')
|
||||
|
||||
|
||||
c.find('FindFirstUnusedColour').type = 'void'
|
||||
c.find('FindFirstUnusedColour.r').pyInt = True
|
||||
c.find('FindFirstUnusedColour.g').pyInt = True
|
||||
c.find('FindFirstUnusedColour.b').pyInt = True
|
||||
@@ -78,6 +88,7 @@ def run():
|
||||
c.find('GetMaskGreen').pyInt = True
|
||||
c.find('GetMaskBlue').pyInt = True
|
||||
|
||||
c.find('GetOrFindMaskColour').type = 'void'
|
||||
c.find('GetOrFindMaskColour.r').pyInt = True
|
||||
c.find('GetOrFindMaskColour.g').pyInt = True
|
||||
c.find('GetOrFindMaskColour.b').pyInt = True
|
||||
@@ -85,9 +96,153 @@ def run():
|
||||
c.find('GetOrFindMaskColour.g').out = True
|
||||
c.find('GetOrFindMaskColour.b').out = True
|
||||
|
||||
|
||||
c.find('RGBValue.red').pyInt = True
|
||||
c.find('RGBValue.green').pyInt = True
|
||||
c.find('RGBValue.blue').pyInt = True
|
||||
c.find('RGBValue.RGBValue.r').pyInt = True
|
||||
c.find('RGBValue.RGBValue.g').pyInt = True
|
||||
c.find('RGBValue.RGBValue.b').pyInt = True
|
||||
|
||||
|
||||
c.addCppMethod('int', '__nonzero__', '()', 'return self->IsOk();')
|
||||
|
||||
c.addPyMethod('ConvertToBitmap', '(self, depth=-1)', """\
|
||||
bmp = wx.Bitmap(self, depth)
|
||||
return bmp
|
||||
""")
|
||||
c.addPyMethod('ConvertToMonoBitmap', '(self, red, green, blue)', """\
|
||||
mono = self.ConvertToMono( red, green, blue )
|
||||
bmp = wx.Bitmap( mono, 1 )
|
||||
return bmp
|
||||
""")
|
||||
|
||||
|
||||
c.addCppMethod('wxImage*', 'AdjustChannels',
|
||||
'(double factor_red, double factor_green, double factor_blue, double factor_alpha=1.0)',
|
||||
doc="""\n
|
||||
AdjustChannels(factor_red, factor_green, factor_blue, factor_alpha=1.0)\n
|
||||
This function muliplies all 4 channels (red, green, blue, alpha) with
|
||||
a factor (around 1.0). Useful for gamma correction, colour correction
|
||||
and to add a certain amount of transparency to a image (fade in fade
|
||||
out effects). If factor_alpha is given but the original image has no
|
||||
alpha channel then a alpha channel will be added.
|
||||
""",
|
||||
body="""\
|
||||
wxCHECK_MSG( self->Ok(), NULL, wxT("invalid image") );
|
||||
|
||||
wxImage* dest = new wxImage( self->GetWidth(), self->GetHeight(), false );
|
||||
wxCHECK_MSG( dest && dest->IsOk(), NULL, wxT("unable to create image") );
|
||||
|
||||
unsigned rgblen = 3 * self->GetWidth() * self->GetHeight();
|
||||
unsigned alphalen = self->GetWidth() * self->GetHeight();
|
||||
unsigned char* src_data = self->GetData();
|
||||
unsigned char* src_alpha = self->GetAlpha();
|
||||
unsigned char* dst_data = dest->GetData();
|
||||
unsigned char* dst_alpha = NULL;
|
||||
|
||||
// adjust rgb
|
||||
if ( factor_red == 1.0 && factor_green == 1.0 && factor_blue == 1.0)
|
||||
{
|
||||
// nothing to do for RGB
|
||||
memcpy(dst_data, src_data, rgblen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// rgb pixel for pixel
|
||||
for ( unsigned i = 0; i < rgblen; i= i + 3 )
|
||||
{
|
||||
dst_data[i] = (unsigned char) wxMin( 255, (int) (factor_red * src_data[i]) );
|
||||
dst_data[i + 1] = (unsigned char) wxMin( 255, (int) (factor_green * src_data[i + 1]) );
|
||||
dst_data[i + 2] = (unsigned char) wxMin( 255, (int) (factor_blue * src_data[i + 2]) );
|
||||
}
|
||||
}
|
||||
|
||||
// adjust the mask colour
|
||||
if ( self->HasMask() )
|
||||
{
|
||||
dest->SetMaskColour((unsigned char) wxMin( 255, (int) (factor_red * self->GetMaskRed() ) ),
|
||||
(unsigned char) wxMin( 255, (int) (factor_green * self->GetMaskGreen() ) ),
|
||||
(unsigned char) wxMin( 255, (int) (factor_blue * self->GetMaskBlue() ) ) );
|
||||
}
|
||||
|
||||
// adjust the alpha channel
|
||||
if ( src_alpha )
|
||||
{
|
||||
// source image already has alpha information
|
||||
dest->SetAlpha(); // create an empty alpha channel (not initialized)
|
||||
dst_alpha = dest->GetAlpha();
|
||||
|
||||
wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );
|
||||
|
||||
if ( factor_alpha == 1.0)
|
||||
{
|
||||
// no need to adjust
|
||||
memcpy(dst_alpha, src_alpha, alphalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// alpha value for alpha value
|
||||
for ( unsigned i = 0; i < alphalen; ++i )
|
||||
{
|
||||
dst_alpha[i] = (unsigned char) wxMin( 255, (int) (factor_alpha * src_alpha[i]) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( factor_alpha != 1.0 )
|
||||
{
|
||||
// no alpha yet but we want to adjust -> create
|
||||
dest->SetAlpha(); // create an empty alpha channel (not initialized)
|
||||
dst_alpha = dest->GetAlpha();
|
||||
|
||||
wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );
|
||||
|
||||
for ( unsigned i = 0; i < alphalen; ++i )
|
||||
{
|
||||
dst_alpha[i] = (unsigned char) wxMin( 255, (int) (factor_alpha * 255) );
|
||||
}
|
||||
}
|
||||
|
||||
// do we have an alpha channel and a mask in the new image?
|
||||
if ( dst_alpha && dest->HasMask() )
|
||||
{
|
||||
// make the mask transparent honoring the alpha channel
|
||||
const unsigned char mr = dest->GetMaskRed();
|
||||
const unsigned char mg = dest->GetMaskGreen();
|
||||
const unsigned char mb = dest->GetMaskBlue();
|
||||
|
||||
for ( unsigned i = 0; i < alphalen; ++i )
|
||||
{
|
||||
int n = i * 3;
|
||||
dst_alpha[i] = ( dst_data[n] == mr && dst_data[n + 1] == mg && dst_data[n + 2] == mb )
|
||||
? wxIMAGE_ALPHA_TRANSPARENT
|
||||
: dst_alpha[i];
|
||||
}
|
||||
|
||||
// remove the mask now
|
||||
dest->SetMask(false);
|
||||
}
|
||||
|
||||
return dest;
|
||||
""")
|
||||
|
||||
#%property(AlphaBuffer, GetAlphaBuffer, SetAlphaBuffer)
|
||||
#%property(AlphaData, GetAlphaData, SetAlphaData)
|
||||
#%property(Data, GetData, SetData)
|
||||
#%property(DataBuffer, GetDataBuffer, SetDataBuffer)
|
||||
|
||||
c.addProperty('Width GetWidth')
|
||||
c.addProperty('Height GetHeight')
|
||||
c.addProperty('MaskBlue GetMaskBlue')
|
||||
c.addProperty('MaskGreen GetMaskGreen')
|
||||
c.addProperty('MaskRed GetMaskRed')
|
||||
c.addProperty('Type GetType SetType')
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------
|
||||
c = module.find('wxImageHistogram')
|
||||
setParamsPyInt('MakeKey')
|
||||
c.find('FindFirstUnusedColour').type = 'void'
|
||||
c.find('FindFirstUnusedColour.r').pyInt = True
|
||||
c.find('FindFirstUnusedColour.g').pyInt = True
|
||||
c.find('FindFirstUnusedColour.b').pyInt = True
|
||||
@@ -99,6 +254,8 @@ def run():
|
||||
c.find('FindFirstUnusedColour.b').out = True
|
||||
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
module.find('wxIMAGE_ALPHA_TRANSPARENT').pyInt = True
|
||||
module.find('wxIMAGE_ALPHA_OPAQUE').pyInt = True
|
||||
|
||||
|
||||
126
unittests/test_image.py
Normal file
126
unittests/test_image.py
Normal file
@@ -0,0 +1,126 @@
|
||||
import imp_unittest, unittest
|
||||
import wtc
|
||||
import wx
|
||||
import os
|
||||
|
||||
pngFile = os.path.join(os.path.dirname(__file__), 'toucan.png')
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class image_Tests(wtc.WidgetTestCase):
|
||||
|
||||
def test_imageCtor1(self):
|
||||
img = wx.Image()
|
||||
self.assertTrue(not img.IsOk())
|
||||
img.Create(100,100)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor2(self):
|
||||
img = wx.Image(100,100)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor3(self):
|
||||
img = wx.Image(wx.Size(100,100))
|
||||
self.assertTrue(img.IsOk())
|
||||
img = wx.Image((100,100))
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor4(self):
|
||||
self.fail("data buffer support TBI")
|
||||
import array
|
||||
w = h = 10
|
||||
buf = array.array('B', '\0' * (w*h*3))
|
||||
img = wx.Image(w, h, buf, True)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor5(self):
|
||||
return
|
||||
self.fail("data buffer support TBI")
|
||||
import array
|
||||
w = h = 10
|
||||
buf = array.array('B', '\0' * (w*h*3))
|
||||
alpha = array.array('B', '\0' * (w*h))
|
||||
img = wx.Image(w, h, buf, alpha, True)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor6(self):
|
||||
img = wx.Image(pngFile, wx.BITMAP_TYPE_PNG)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor7(self):
|
||||
img = wx.Image(pngFile, 'image/png')
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor8(self):
|
||||
self.fail('stream support TBI')
|
||||
data = open(pngFile, 'rb').read()
|
||||
import StringIO
|
||||
stream = StringIO.StringIO(data)
|
||||
img = wx.Image(stream, wx.BITMAP_TYPE_PNG)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
def test_imageCtor9(self):
|
||||
return
|
||||
self.fail('stream support TBI')
|
||||
data = open(pngFile, 'rb').read()
|
||||
import StringIO
|
||||
stream = StringIO.StringIO(data)
|
||||
img = wx.Image(stream, 'image/png')
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
|
||||
|
||||
def test_imageNestedClasses(self):
|
||||
rgb = wx.Image.RGBValue(1,2,3)
|
||||
self.assertEqual(rgb.red, 1)
|
||||
self.assertEqual(rgb.green, 2)
|
||||
self.assertEqual(rgb.blue, 3)
|
||||
rgb.red = 4
|
||||
rgb.green = 5
|
||||
rgb.blue = 6
|
||||
|
||||
hsv = wx.Image.HSVValue(1.1, 1.2, 1.3)
|
||||
self.assertEqual(hsv.hue, 1.1)
|
||||
self.assertEqual(hsv.saturation, 1.2)
|
||||
self.assertEqual(hsv.value, 1.3)
|
||||
hsv.hue = 2.1
|
||||
hsv.saturation = 2.2
|
||||
hsv.value = 2.3
|
||||
|
||||
|
||||
def test_imageRGBHSV(self):
|
||||
rgb = wx.Image.RGBValue(1,2,3)
|
||||
hsv = wx.Image.RGBtoHSV(rgb)
|
||||
rgb = wx.Image.HSVtoRGB(hsv)
|
||||
self.assertEqual(rgb.red, 1)
|
||||
self.assertEqual(rgb.green, 2)
|
||||
self.assertEqual(rgb.blue, 3)
|
||||
|
||||
|
||||
def test_imageProperties(self):
|
||||
img = wx.Image(pngFile)
|
||||
self.assertTrue(img.IsOk())
|
||||
img.Width
|
||||
img.Height
|
||||
img.MaskRed
|
||||
img.MaskGreen
|
||||
img.MaskBlue
|
||||
img.Type
|
||||
|
||||
|
||||
def test_imageMethodChain(self):
|
||||
img = wx.Image(100,100).Rescale(75,75).Resize((100,100), (0,0), 40,60,80)
|
||||
self.assertTrue(img.IsOk())
|
||||
|
||||
|
||||
def test_imageOtherStuff(self):
|
||||
img = wx.Image(pngFile)
|
||||
self.assertTrue(img.IsOk())
|
||||
r, g, b = img.FindFirstUnusedColour()
|
||||
r, g, b = img.GetOrFindMaskColour()
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user