add sorted to pycompat
[PyX.git] / contrib / epstopng.py
blob6f671654ad2bcd8afa93fc11a9eb2d905f16fa1c
1 #!/usr/bin/env python
2 # -*- encoding: utf-8 -*-
5 # Copyright (C) 2003 André Wobst <wobsta@users.sourceforge.net>
7 # epstopng is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # epstopng is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with epstopng; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 # TODO: - set dpi in png (don't know how to do this in PIL)
22 # - this is much too slow --- consider a rewrite in C
25 import getopt, sys, os, StringIO, re, math
26 import Image # we use the python image library (PIL)
29 progname = "epstopng v0.1: eps to transparent antialiased png converter"
32 def epstopng(epsname, pngname, resolution, scale, transparent, gsname, quiet):
33 sys.stderr.write("run ghostscript to create a %i times larger non-antialiased image ... " % scale)
34 gsout = os.popen("%s -dEPSCrop -dNOPAUSE -dQUIET -dBATCH -sDEVICE=ppmraw -sOutputFile=- -r%i %s" % (gsname, resolution*scale, epsname))
35 input = Image.open(StringIO.StringIO(gsout.read())).convert("RGB") # ensure rgb here
36 output = Image.new("RGBA", [(x+scale-1)/scale for x in input.size])
37 sys.stderr.write("done\n")
38 sys.stderr.write("image size is %ix%i\n" % output.size)
40 inputdata = input.getdata() # getdata instead of getpixel leads to about a factor of 2 in running time
41 # similar effect with putdata possible??? (didn't got that running)
42 inputsizex, inputsizey = input.size
43 # loop over the small image
44 for x in range(output.size[0]):
45 sys.stderr.write("transparent antialias conversion ... %5.2f %%\r" % (x*100.0/output.size[0]))
46 for y in range(output.size[1]):
47 # r, g, b: sum of the rgb-values; u: number of non-transparent pixels
48 r = g = b = u = 0
49 # loop over the pixels of the large image to be used for pixel (x, y)
50 for xo in range(x*scale, min((x+1)*scale, inputsizex-1)):
51 for yo in range(y*scale, min((y+1)*scale, inputsizey-1)):
52 ro, go, bo = inputdata[xo+inputsizex*yo]
53 if (ro, go, bo) != transparent:
54 r += ro
55 g += go
56 b += bo
57 u += 1
58 if u:
59 output.putpixel((x, y), (r/u, g/u, b/u, (u*255)/(scale*scale)))
60 else:
61 output.putpixel((x, y), (255, 255, 255, 0))
62 sys.stderr.write("transparent antialias conversion ... done \n")
64 output.save(pngname)
67 def usage():
68 print progname
69 print "Copyright (C) 2003 André Wobst <wobsta@users.sourceforge.net>"
70 print "usage: epstopng [options] <eps-file>"
71 print "-h, --help: show this help"
72 print "-q, --quiet: be quiet"
73 print "-o, --output <file>: output file name; must be set"
74 print "-r, --resolution <dpi>: resolution; default: 100"
75 print "-s, --scale <scale>: input scale for antialias; default: 4"
76 print "-t, --transparent (<r>, <g>, <b>): transparent color; default: (255, 255, 255)"
77 print "-g, --gsname <name>: name of the gs interpreter (gs version >= 8.0 needed!); default: \"gs\""
80 def main():
81 try:
82 opts, args = getopt.getopt(sys.argv[1:], "hqo:r:s:t:g:", ["help", "quiet", "output", "resolution", "scale", "transparent", "gsname"])
83 except getopt.GetoptError:
84 # print help information and exit:
85 usage()
86 sys.exit(2)
87 output = None
88 resolution = 100
89 scale = 4
90 transparent = (255, 255, 255)
91 gsname = "gs"
92 quiet = 0
93 for o, a in opts:
94 if o in ("-h", "--help"):
95 usage()
96 sys.exit()
97 if o in ("-o", "--output"):
98 output = a
99 if o in ("-r", "--resolution"):
100 resolution = int(a)
101 if o in ("-s", "--scale"):
102 scale = int(a)
103 if o in ("-t", "--transparent"):
104 m = re.compile(r"\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$").match(a)
105 if not m:
106 raise RuntimeError("transparent argument does not match")
107 transparent = [int(x) for x in m.groups()]
108 if o in ("-g", "--gsname"):
109 gsname = a
110 if len(args) == 1:
111 input = args[0]
112 elif len(args):
113 raise RuntimeError("can't handle several input files")
114 else:
115 raise RuntimeError("must specify an input file (reading from stdin is not yet supported)")
116 if output is None:
117 raise RuntimeError("you must specify an output file name")
118 if not quiet:
119 sys.stderr.write(progname + "\n")
120 epstopng(input, output, resolution, scale, transparent, gsname, quiet)
123 if __name__ == "__main__":
124 main()