pipcolours 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #!/usr/bin/env python
  2. # $URL: http://pypng.googlecode.com/svn/trunk/code/pipcolours $
  3. # $Rev: 96 $
  4. # pipcolours - extract all colours present in source image.
  5. def colours(out, inp):
  6. import itertools
  7. import png
  8. r = png.Reader(file=inp)
  9. _,_,pixels,info = r.asDirect()
  10. planes = info['planes']
  11. col = set()
  12. for row in pixels:
  13. # Ewgh, side effects on col
  14. map(col.add, png.group(row, planes))
  15. col,planes = channel_reduce(col, planes)
  16. col = list(col)
  17. col.sort()
  18. col = list(itertools.chain(*col))
  19. width = len(col)//planes
  20. greyscale = planes in (1,2)
  21. alpha = planes in (2,4)
  22. bitdepth = info['bitdepth']
  23. w = png.Writer(width, 1,
  24. bitdepth=bitdepth, greyscale=greyscale, alpha=alpha)
  25. w.write(out, [col])
  26. def channel_reduce(col, planes):
  27. """Attempt to reduce the number of channels in the set of
  28. colours."""
  29. if planes >= 3:
  30. def isgrey(c):
  31. return c[0] == c[1] == c[2]
  32. if min(map(isgrey, col)) == True:
  33. # Every colour is grey.
  34. col = set(map(lambda x: x[0::3], col))
  35. planes -= 2
  36. return col,planes
  37. def main(argv=None):
  38. import sys
  39. if argv is None:
  40. argv = sys.argv
  41. argv = argv[1:]
  42. if len(argv) > 0:
  43. f = open(argv[0], 'rb')
  44. else:
  45. f = sys.stdin
  46. return colours(sys.stdout, f)
  47. if __name__ == '__main__':
  48. main()