1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipwindow $
# $Rev: 173 $
# pipwindow
# Tool to crop/expand an image to a rectangular window. Come the
# revolution this tool will allow the image and the window to be placed
# arbitrarily (in particular the window can be bigger than the picture
# and/or overlap it only partially) and the image can be OpenGL style
# border/repeat effects (repeat, mirrored repeat, clamp, fixed
# background colour, background colour from source file). For now it
# only acts as crop. The window must be no greater than the image in
# both x and y.
def window(tl, br, inp, out):
"""Place a window onto the image and cut-out the resulting
rectangle. The window is an axis aligned rectangle opposite corners
at *tl* and *br* (each being an (x,y) pair). *inp* specifies the
input file which should be a PNG image.
"""
import png
r = png.Reader(file=inp)
x,y,pixels,meta = r.asDirect()
if not (0 <= tl[0] < br[0] <= x):
raise NotImplementedError()
if not (0 <= tl[1] < br[1] <= y):
raise NotImplementedError()
# Compute left and right bounds for each row
l = tl[0] * meta['planes']
r = br[0] * meta['planes']
def itercrop():
"""An iterator to perform the crop."""
for i,row in enumerate(pixels):
if i < tl[1]:
continue
if i >= br[1]:
# Same as "raise StopIteration"
return
yield row[l:r]
meta['size'] = (br[0]-tl[0], br[1]-tl[1])
w = png.Writer(**meta)
w.write(out, itercrop())
def main(argv=None):
import sys
if argv is None:
argv = sys.argv
argv = argv[1:]
tl = (0,0)
br = tuple(map(int, argv[:2]))
if len(argv) >= 4:
tl = br
br = tuple(map(int, argv[2:4]))
if len(argv) in (2, 4):
f = sys.stdin
else:
f = open(argv[-1], 'rb')
return window(tl, br, f, sys.stdout)
if __name__ == '__main__':
main()
|