mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-16 09:40:07 +01:00
Add wx.Image.ConvertToRegion allowing to construct a region from an image without needing to make a bitmap first.
This commit is contained in:
@@ -26,14 +26,17 @@ class TestFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_RIGHT_UP, self.OnExit)
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
|
||||
self.bmp = images.Vippi.GetBitmap()
|
||||
img = images.Vippi.GetImage()
|
||||
if img.HasAlpha():
|
||||
img.ConvertAlphaToMask()
|
||||
self.img = img
|
||||
self.bmp = wx.Bitmap(img)
|
||||
|
||||
w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
|
||||
self.SetClientSize( (w, h) )
|
||||
|
||||
if wx.Platform != "__WXMAC__":
|
||||
# wxMac clips the tooltip to the window shape, YUCK!!!
|
||||
self.SetToolTip("Right-click to close the window\n"
|
||||
"Double-click the image to set/unset the window shape")
|
||||
self.SetToolTip("Right-click to close the window\n"
|
||||
"Double-click the image to set/unset the window shape")
|
||||
|
||||
if wx.Platform == "__WXGTK__":
|
||||
# wxGTK requires that the window be created before you can
|
||||
@@ -50,9 +53,11 @@ class TestFrame(wx.Frame):
|
||||
|
||||
def SetWindowShape(self, *evt):
|
||||
# Use the bitmap's mask to determine the region
|
||||
r = wx.Region(self.bmp)
|
||||
#r = wx.Region(self.bmp)
|
||||
r = self.img.ConvertToRegion()
|
||||
self.hasShape = self.SetShape(r)
|
||||
|
||||
|
||||
def OnDoubleClick(self, evt):
|
||||
if self.hasShape:
|
||||
self.SetShape(wx.Region())
|
||||
|
||||
79
etg/image.py
79
etg/image.py
@@ -496,6 +496,85 @@ def run():
|
||||
c.addProperty('Type GetType SetType')
|
||||
|
||||
|
||||
c.addCppMethod('wxRegion*', 'ConvertToRegion',
|
||||
'(int R=-1, int G=-1, int B=-1, int tolerance=0)',
|
||||
doc="""\
|
||||
Create a :class:`wx.Region` where the transparent areas match the given RGB values.
|
||||
|
||||
If the RGB values are not given, then the image's mask colour
|
||||
components will be used instead. If a non-zero tolerance is given
|
||||
then the pixels that fall into the range of (R,G,B) to
|
||||
(R+tolerance, G+tolerance, B+tolerance) will be considered to be
|
||||
transparent.
|
||||
|
||||
If there are no pixels matching the transparent colours then the
|
||||
region returned will match the image's full dimensions.
|
||||
|
||||
:param int `R`: The red component of the transparent colour.
|
||||
:param int `G`: The red component of the transparent colour.
|
||||
:param int `B`: The red component of the transparent colour.
|
||||
:param int `tolerance`: Broadens the range of colours that will
|
||||
be considered transparent.
|
||||
:returns: a :class:`wx.Region` object.
|
||||
""",
|
||||
body="""\
|
||||
wxRegion* region = new wxRegion();
|
||||
unsigned char hiR, hiG, hiB;
|
||||
|
||||
if (R == -1) { R = self->GetMaskRed(); }
|
||||
if (G == -1) { G = self->GetMaskGreen(); }
|
||||
if (B == -1) { B = self->GetMaskBlue(); }
|
||||
|
||||
// Make sure nothing out of range was passed
|
||||
R &= 0xFF;
|
||||
G &= 0xFF;
|
||||
B &= 0xFF;
|
||||
|
||||
hiR = (unsigned char)wxMin(0xFF, R + tolerance);
|
||||
hiG = (unsigned char)wxMin(0xFF, G + tolerance);
|
||||
hiB = (unsigned char)wxMin(0xFF, B + tolerance);
|
||||
|
||||
// Loop through the image row by row, pixel by pixel, building up
|
||||
// rectangles to add to the region.
|
||||
int width = self->GetWidth();
|
||||
int height = self->GetHeight();
|
||||
|
||||
for (int y=0; y < height; y++)
|
||||
{
|
||||
wxRect rect;
|
||||
rect.y = y;
|
||||
rect.height = 1;
|
||||
|
||||
for (int x=0; x < width; x++)
|
||||
{
|
||||
// search for a continuous range of non-transparent pixels
|
||||
int x0 = x;
|
||||
while ( x < width)
|
||||
{
|
||||
unsigned char red = self->GetRed(x,y);
|
||||
unsigned char grn = self->GetGreen(x,y);
|
||||
unsigned char blu = self->GetBlue(x,y);
|
||||
if (( red >= R && red <= hiR) &&
|
||||
( grn >= G && grn <= hiG) &&
|
||||
( blu >= B && blu <= hiB)) // It's transparent
|
||||
break;
|
||||
x++;
|
||||
}
|
||||
|
||||
// Add the run of non-transparent pixels (if any) to the region
|
||||
if (x > x0) {
|
||||
rect.x = x0;
|
||||
rect.width = x - x0;
|
||||
region->Union(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (region->IsEmpty())
|
||||
region->Union(0, 0, width, height);
|
||||
return region;
|
||||
""")
|
||||
|
||||
|
||||
# For compatibility:
|
||||
module.addPyFunction('EmptyImage', '(width=0, height=0, clear=True)',
|
||||
deprecated="Use :class:`Image` instead.",
|
||||
|
||||
Reference in New Issue
Block a user