Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d35509a

Browse files
committed
Contributed modules by Riccardo Trocca. Extended pixmap wrapper, NumPy visualiser and QuickTime to images.
1 parent fdd2269 commit d35509a

4 files changed

Lines changed: 614 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'''
2+
A really quick and dirty hack to extend PixMapWrapper
3+
They are mere copies of the toImage and fromImage methods.
4+
Riccardo Trocca ([email protected])
5+
'''
6+
from PixMapWrapper import *
7+
import Numeric
8+
9+
class ExtPixMapWrapper(PixMapWrapper):
10+
11+
def toNumeric(self):
12+
13+
data = self.tostring()[1:] + chr(0)
14+
bounds = self.bounds
15+
tmp=Numeric.fromstring(data,Numeric.UnsignedInt8)
16+
#tmp.shape=(bounds[3]-bounds[1],bounds[2]-bounds[0],4)
17+
tmp.shape=(bounds[2]-bounds[0],bounds[3]-bounds[1],4)
18+
return Numeric.transpose(tmp,(1,0,2))
19+
20+
def fromNumeric(self,num):
21+
s=num.shape
22+
x=num.shape[1]
23+
y=num.shape[0]
24+
#bands=1 Greyscale image
25+
#bands=3 RGB image
26+
#bands=4 RGBA image
27+
if len(s)==2:
28+
bands=1
29+
num=Numeric.resize(num,(y,x,1))
30+
else:
31+
bands=num.shape[2]
32+
33+
if bands==1:
34+
num=Numeric.concatenate((num,num,num),2)
35+
bands=3
36+
if bands==3:
37+
alpha=Numeric.ones((y,x))*255
38+
alpha.shape=(y,x,1)
39+
num=Numeric.concatenate((num,alpha),2)
40+
41+
data=chr(0)+Numeric.transpose(num,(1,0,2)).astype(Numeric.UnsignedInt8).tostring()
42+
PixMapWrapper.fromstring(self,data,x,y)
43+
44+
45+
46+
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
'''
2+
ImageMac.py by Trocca Riccardo ([email protected])
3+
This module provides functions to display images and Numeric arrays
4+
It provides two classes ImageMacWin e NumericMacWin and two simple methods showImage and
5+
showNumeric.
6+
7+
They work like this:
8+
showImage(Image,"optional window title",zoomFactor)
9+
the same for showNumeric
10+
zoomfactor (defaults to 1) allows to zoom in the image by a factor of 1x 2x 3x and so on
11+
I did't try with a 0.5x or similar.
12+
The windows don't provide a scrollbar or a resize box.
13+
Probably a better solution (and more similar to the original implementation in PIL and NumPy)
14+
would be to save a temp file is some suitable format and then make an application (through appleevents) to open it.
15+
Good guesses should be GraphicConverter or PictureViewer.
16+
17+
However the classes ImageMacWin e NumericMacWin use an extended version of PixMapWrapper in order to
18+
provide an image buffer and then blit it in the window.
19+
20+
Being one of my first experiences with Python I didn't use Exceptions to signal error conditions, sorry.
21+
22+
'''
23+
import W
24+
import Qd
25+
from ExtPixMapWrapper import *
26+
from Numeric import *
27+
import Image
28+
import macfs
29+
30+
class ImageMacWin(W.Window):
31+
32+
def __init__(self,size=(300,300),title="ImageMacWin"):
33+
self.pm=ExtPixMapWrapper()
34+
self.empty=1
35+
self.size=size
36+
W.Window.__init__(self,size,title)
37+
38+
def Show(self,image,resize=0):
39+
#print "format: ", image.format," size: ",image.size," mode: ",image.mode
40+
#print "string len :",len(image.tostring())
41+
self.pm.fromImage(image)
42+
self.empty=0
43+
if resize:
44+
self.size=(image.size[0]*resize,image.size[1]*resize)
45+
W.Window.do_resize(self,self.size[0],self.size[1],self.wid)
46+
self.do_drawing()
47+
48+
def do_drawing(self):
49+
#print "do_drawing"
50+
self.SetPort()
51+
Qd.RGBForeColor( (0,0,0) )
52+
Qd.RGBBackColor((65535, 65535, 65535))
53+
Qd.EraseRect((0,0,self.size[0],self.size[1]))
54+
if not self.empty:
55+
#print "should blit"
56+
self.pm.blit(0,0,self.size[0],self.size[1])
57+
58+
def do_update(self,macoswindowid,event):
59+
#print "update"
60+
self.do_drawing()
61+
62+
class NumericMacWin(W.Window):
63+
64+
def __init__(self,size=(300,300),title="ImageMacWin"):
65+
self.pm=ExtPixMapWrapper()
66+
self.empty=1
67+
self.size=size
68+
W.Window.__init__(self,size,title)
69+
70+
def Show(self,num,resize=0):
71+
#print "shape: ", num.shape
72+
#print "string len :",len(num.tostring())
73+
self.pm.fromNumeric(num)
74+
self.empty=0
75+
if resize:
76+
self.size=(num.shape[1]*resize,num.shape[0]*resize)
77+
W.Window.do_resize(self,self.size[0],self.size[1],self.wid)
78+
self.do_drawing()
79+
80+
def do_drawing(self):
81+
#print "do_drawing"
82+
self.SetPort()
83+
Qd.RGBForeColor( (0,0,0) )
84+
Qd.RGBBackColor((65535, 65535, 65535))
85+
Qd.EraseRect((0,0,self.size[0],self.size[1]))
86+
if not self.empty:
87+
#print "should blit"
88+
self.pm.blit(0,0,self.size[0],self.size[1])
89+
90+
def do_update(self,macoswindowid,event):
91+
#print "update"
92+
self.do_drawing()
93+
94+
'''
95+
Some utilities: convert an Image to a NumPy array and viceversa.
96+
The Image2Numeric function doesn't make any color space conversion.
97+
The Numeric2Image function returns an L or RGB or RGBA images depending on the shape of
98+
the array:
99+
(x,y) -> 'L'
100+
(x,y,1) -> 'L'
101+
(x,y,3) -> 'RGB'
102+
(x,y,4) -> 'RGBA'
103+
'''
104+
def Image2Numeric(im):
105+
tmp=fromstring(im.tostring(),UnsignedInt8)
106+
107+
if (im.mode=='RGB')|(im.mode=='YCbCr'):
108+
bands=3
109+
110+
if (im.mode=='RGBA')|(im.mode=='CMYK'):
111+
bands=4
112+
113+
if (im.mode=='L'):
114+
bands=1
115+
116+
tmp.shape=(im.size[0],im.size[1],bands)
117+
return transpose(tmp,(1,0,2))
118+
119+
def Numeric2Image(num):
120+
#sometimes a monoband image's shape can be (x,y,1), other times just (x,y). Here w deal with both
121+
if len(num.shape)==3:
122+
bands=num.shape[2]
123+
if bands==1:
124+
mode='L'
125+
elif bands==3:
126+
mode='RGB'
127+
else:
128+
mode='RGBA'
129+
return Image.fromstring(mode,(num.shape[1],num.shape[0]),transpose(num,(1,0,2)).astype(UnsignedInt8).tostring())
130+
else:
131+
return Image.fromstring('L',(num.shape[1],num.shape[0]),transpose(num).astype(UnsignedInt8).tostring())
132+
133+
def showImage(im,title="ImageWin",zoomFactor=1):
134+
imw=ImageMacWin((300,200),title)
135+
imw.open()
136+
try:
137+
imw.Show(im,zoomFactor )
138+
except MemoryError,e:
139+
imw.close()
140+
print "ImageMac.showImage: Insufficient Memory"
141+
142+
143+
def showNumeric(num,title="NumericWin",zoomFactor=1):
144+
#im=Numeric2Image(num)
145+
numw=NumericMacWin((300,200),title)
146+
numw.open()
147+
try:
148+
numw.Show(num,zoomFactor )
149+
except MemoryError:
150+
numw.close()
151+
print "ImageMac.showNumeric Insufficient Memory"
152+
153+
'''
154+
GimmeImage pops up a file dialog and asks for an image file.
155+
it returns a PIL image.
156+
Optional argument: a string to be displayed by the dialog.
157+
'''
158+
159+
def GimmeImage(prompt="Image File:"):
160+
import macfs
161+
fsspec, ok = macfs.PromptGetFile(prompt)
162+
if ok:
163+
path = fsspec.as_pathname()
164+
return Image.open(path)
165+
return None
166+
167+
'''
168+
This is just some experimental stuff:
169+
Filter3x3 a convolution filter (too slow use signal tools instead)
170+
diffBWImage subtracts 2 images contained in NumPy arrays
171+
averageN it computes the average of a list incrementally
172+
BWImage converts an RGB or RGBA image (in a NumPy array) to BW
173+
SplitBands splits the bands of an Image (inside a NumPy)
174+
NumHisto and PlotHisto are some experiments to plot an intesity histogram
175+
'''
176+
177+
def Filter3x3(mul,fi,num):
178+
(a,b,c,d,e,f,g,h,i)=fi
179+
print fi
180+
num.shape=(num.shape[0],num.shape[1])
181+
res=zeros(num.shape)
182+
for x in range(1,num.shape[0]-1):
183+
for y in range(1,num.shape[1]-1):
184+
xb=x-1
185+
xa=x+1
186+
yb=y-1
187+
ya=y+1
188+
res[x,y]=int((a*num[xb,yb]+b*num[x,yb]+c*num[xa,yb]+d*num[xb,y]+e*num[x,y]+f*num[xa,y]+g*num[xb,ya]+h*num[x,ya]+i*num[xa,ya])/mul)
189+
return res
190+
191+
def diffBWImage(num1,num2):
192+
return 127+(num1-num2)/2
193+
194+
def averageN(N,avrg,new):
195+
return ((N-1)*avrg+new)/N
196+
197+
def BWImage(num):
198+
if num.shape[2]==3:
199+
bw=array(((0.3086,0.6094,0.0820)))
200+
else:
201+
bw=array(((0.3086,0.6094,0.0820,0)))
202+
res=innerproduct(num,bw)
203+
res.shape=(res.shape[0],res.shape[1])
204+
return res
205+
206+
def SplitBands(num):
207+
x=num.shape[0]
208+
y=num.shape[1]
209+
if num.shape[2]==3:
210+
return (reshape(num[:,:,0],(x,y)),reshape(num[:,:,1],(x,y)),reshape(num[:,:,2],(x,y)))
211+
else:
212+
return (reshape(num[:,:,0],(x,y)),reshape(num[:,:,1],(x,y)),reshape(num[:,:,2],(x,y)),reshape(num[:,:,3],(x,y)))
213+
214+
def NumHisto(datas):
215+
#print "type(datas) ",type(datas)
216+
a=ravel(datas)
217+
n=searchsorted(sort(a),arange(0,256))
218+
n=concatenate([n,[len(a)]])
219+
return n[1:]-n[:-1]
220+
221+
def PlotHisto(datas,ratio=1):
222+
from graphite import *
223+
from MLab import max
224+
h=NumHisto(datas)
225+
#print "histo: ",h
226+
#print "histo.shape: ",h.shape
227+
maxval=max(h)
228+
#print "maxval ",maxval
229+
h.shape=(256,1)
230+
x=arange(0,256)
231+
x.shape=(256,1)
232+
datah=concatenate([x,h],1)
233+
print "data: "
234+
print datah
235+
g=Graph()
236+
g.datasets.append(Dataset(datah))
237+
f0=PointPlot()
238+
f0.lineStyle = LineStyle(width=2, color=red, kind=SOLID)
239+
g.formats = [f0]
240+
g.axes[X].range = [0,255]
241+
g.axes[X].tickMarks[0].spacing = 10
242+
#g.axes[X].tickMarks[0].labels = "%d"
243+
g.axes[Y].range = [0,maxval/ratio]
244+
g.bottom = 370
245+
g.top =10
246+
g.left=10
247+
g.right=590
248+
249+
genOutput(g,'QD',size=(600,400))
250+
251+
def test():
252+
import MacOS
253+
import Image
254+
import ImageFilter
255+
import Numeric
256+
fsspec, ok = macfs.PromptGetFile("Image File:")
257+
if ok:
258+
path = fsspec.as_pathname()
259+
im=Image.open(path)
260+
#im2=im.filter(ImageFilter.SMOOTH)
261+
showImage(im,"normal")
262+
num=Image2Numeric(im)
263+
#num=Numeric.transpose(num,(1,0,2))
264+
265+
showNumeric(num,"Numeric")
266+
267+
print "num.shape ",num.shape
268+
showImage(Numeric2Image(num),"difficile")
269+
#showImage(im.filter(ImageFilter.SMOOTH),"smooth")
270+
#showImage(im.filter(ImageFilter.FIND_EDGES).filter(ImageFilter.SHARPEN),"detail")
271+
272+
print "here"
273+
else:
274+
print "did not open file"
275+
276+
if __name__ == '__main__':
277+
test()

0 commit comments

Comments
 (0)