pipwindow 2.0 KB

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