Attachment 'ImgConv.py'
Download 1 # ImgConv.py
2
3 """
4 Based on pyWiki 'Working With Images' @ http://wiki.wxpython.org/index.cgi/WorkingWithImages
5 Modified to properly copy, create or remove any alpha in all conversion permutations.
6
7 Note: The terms "plane", "band", "layer" and "channel" are used interchangibly.
8
9 Tested on Win7 64-bit (6.1.7600) and Win XP SP3 (5.1.2600) using Python 32-bit.
10
11 Platform Windows 6.1.7600
12 Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel) (x86)]
13 Python wx 2.8.10.1
14 Pil 1.1.7
15
16 Ray Pasco
17 pascor(at)verizon(dot)net
18
19 Last modification: 2011-04-02
20
21 This code may be modified and distributed for any purpose whatsoever.
22
23 """
24
25 import sys
26
27 import wx # WxBmap <==> wxImage
28 import Image # wxImage <==> PilImage. Used whenf converting to or from Pil images.
29
30 #------------------------------------------------------------------------------
31
32 # image type image type image type
33 # 1 2 3
34 # wx.Bitmap <==> wx.Image <==> pilImage
35
36 #----------------------------
37
38 def WxBitmapFromPilImage( pilImage, addAlphaLayer=False, delAlphaLayer=False ) :
39 """
40 3 ==> 1
41
42 The default parameter valuess preserve any existing transparency,
43 but do not add one if none exists.
44
45 If the given pilImage mode is RGB, optionally create a new wxImage
46 alpha transparency plane by calling with addAlphaLayer=True.
47
48 If the given pilImage mode is RGBA, optionally create a new wxImage
49 and delete any transparency plane by calling with delAlphaLayer=True.
50
51 If given *both* addAlphaLayer=True *and* delAlphaLayer=True,
52 addAlphaLayer=True will take precidence.
53
54 """
55
56 # Pass on the given parameters.
57 wxImage = WxImageFromPilImage( pilImage, addAlphaLayer, delAlphaLayer )
58 wxBitmap = wxImage.ConvertToBitmap()
59
60 return wxBitmap
61 #end def
62
63 #----------------------------
64
65 def WxImageFromPilImage( pilImage, addAlphaLayer=False, delAlphaLayer=False ) :
66 """
67 3 ==> 2
68
69 The default parameter values preserve any existing transparency,
70 but do not add one if it none exists in the source image.
71
72 If the given source has no alpha, a new image with alpha transparency
73 can be returned by calling with addAlphaLayer=True.
74
75 If the given source image has alpha, a new image without alpha
76 can be returned by calling with delAlphaLayer=True.
77
78 """
79
80 wxImage = wx.EmptyImage( *pilImage.size ) # Has no transparency plane.
81
82 pilMode = pilImage.mode
83 hasAlpha = pilImage.mode[-1] == 'A'
84
85 if hasAlpha or (not hasAlpha and addAlphaLayer) :
86
87 pilImageRGBA = pilImage.copy() # Image mode might now be RGB, not RGBA.
88 if pilImage.mode != 'RGBA' :
89 pilImageRGBA = pilImageRGBA.convert( 'RGBA' )
90 #end if
91 # The image mode is now gauranteed to be RGBA.
92
93 pilImageStr = pilImageRGBA.tostring() # Convert all 4 image planes.
94
95 # Extract just the RGB data
96 pilRgbStr = pilImageRGBA.copy().convert( 'RGB').tostring()
97 wxImage.SetData( pilRgbStr )
98
99 # Extract just the existing pilImage alpha plane data.
100 pilAlphaStr = pilImageStr[3::4] # start at index 3 with a stride (skip) of 4.
101 wxImage.SetAlphaData( pilAlphaStr )
102
103 elif delAlphaLayer or ((not hasAlpha) and (not addAlphaLayer)) :
104
105 pilImageRGB = pilImage.copy().convert( 'RGB' )
106
107 wxImage.SetData( pilImageRGB.tostring() )
108
109 else : # All undecoded parameter permutations. This is for DEBUG.
110
111 print '#### ERROR: ImgConv:WxImageFromPilImage(): Undecoded Parameter Combination.'
112 sys.exit(1)
113
114 #end if
115
116 return wxImage
117
118 #end def
119
120 #----------------------------
121
122 def WxBitmapFromWxImage( wxImage, threshold=128 ) :
123 """
124 2 ==> 1
125
126 Any transparency mask or alpha transparency will be copied, to0.
127 """
128
129 wxBmap = wxImage.ConvertToBitmap()
130
131 return wxBmap
132
133 #end def
134
135 #----------------------------
136
137 def WxImageFromWxBitmap( wxBmap ) :
138 """
139 1 ==> 2
140
141 Any transparency mask or alpha transparency will be copied, to0.
142 """
143 return wx.ImageFromBitmap( wxBmap )
144 #end def
145
146 #------------------------------------------------------------------------------
147
148 def PilImageFromWxBitmap( wxBmap, keepTransp=True, createTransp=False, debug=False ) :
149 """
150 1 ==> 3
151
152 The default parameter values preserve any existing transparency,
153 but do not add one if it none exists in the source image.
154
155 If the given source has no alpha, a new image with alpha transparency
156 can be returned by calling with addAlphaLayer=True.
157
158 If the given source image has alpha, a new image without alpha
159 can be returned by calling with delAlphaLayer=True.
160
161 """
162
163 wxImage = WxImageFromWxBitmap( wxBmap )
164
165 return PilImageFromWxImage( wxImage ) # Always preserves any transparency.
166 #end def
167
168 #----------------------------
169
170 def PilImageFromWxImage( wxImage, keepTransp=True, createTransp=False, debug=False ) :
171 """
172 2 ==> 3
173
174 Default preserves any transparency.
175 """
176
177 # These can never be simultaneous.
178 hasMask = wxImage.HasMask()
179 hasAlpha = wxImage.HasAlpha()
180 if debug :
181 print '>>>> PilImageFromWxImage(): Input Image has Alpha'
182
183 # Always convert a mask into an aplha layer.
184 # Deal with keeping or discarding this alpha later on.
185 if hasMask : # Is always mutually exclusive with hasAlpha.
186
187 if debug :
188 print '>>>> PilImageFromWxImage(): Converting Input Image Mask to Alpha'
189
190 wxImage.InitAlpha() # Covert the separate mask to a 4th alpha layer.
191 hasAlpha = True
192
193 #end if
194
195 image_size = wxImage.GetSize() # All images here have the same size.
196
197 # Create an RGB pilImage and stuff it with RGB data from the wxImage.
198 pilImage = Image.new( 'RGB', image_size )
199 pilImage.fromstring( wxImage.GetData() )
200
201 # May need the separated planes if an RGBA image is needed. later.
202 r_pilImage, g_pilImage, b_pilImage = pilImage.split()
203
204 if hasAlpha :
205
206 if keepTransp : # Ignore createTransp - has no meaning
207
208 if debug :
209 print '>>>> PilImageFromWxImage(): Keeping Transparency'
210
211 # Must recompose the pilImage from 4 layers.
212 r_pilImage, g_pilImage, b_pilImage = pilImage.split()
213
214 # Create a Black L pilImage and stuff it with the alpha data
215 # extracted from the alpha layer of the wxImage.
216 pilImage_L = Image.new( 'L', image_size )
217 pilImage_L.fromstring( wxImage.GetAlphaData() )
218
219 # Create an RGBA PIL image from the 4 layers.
220 pilImage = Image.merge( 'RGBA', (r_pilImage, g_pilImage, b_pilImage, pilImage_L) )
221
222 elif (not keepTransp) :
223
224 # The RGB pilImage can be returned as it is now.
225 if debug :
226 print '>>>> PilImageFromWxImage(): Returning an RGB PIL Image.'
227
228 #end if
229
230 elif (not hasAlpha) and createTransp : # Ignore keepTransp - has no meaning
231
232 if debug :
233 print '>>>> PilImageFromWxImage(): Creating a New Transparency Layer'
234
235 # Create a Black L mode pilImage. The resulting image will still
236 # look the same, but will allow future transparency modification.
237 pilImage_L = Image.new( 'L', image_size )
238
239 # Create an RGBA pil image from the 4 bands.
240 pilImage = Image.merge( 'RGBA', (r_pilImage, g_pilImage, b_pilImage, pilImage_L) )
241
242 #end if
243
244 return pilImage
245
246 #end PilImageFromWxImage def
247
248 #------------------------------------------------------------------------------
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.