-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathImageDemo.py
More file actions
143 lines (116 loc) · 4.62 KB
/
Copy pathImageDemo.py
File metadata and controls
143 lines (116 loc) · 4.62 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from math import sin, pi
from MiscUtils import StringIO
from MiscUtils.Funcs import asclocaltime
from ExamplePage import ExamplePage
try: # GD module
from gd import image as gdImage, gdFontLarge
except ImportError:
gdImage = None
try: # Python Imaging Library
import Image as pilImage, ImageDraw, ImageFont
except ImportError:
try:
from PIL import Image as pilImage, ImageDraw, ImageFont
except ImportError:
pilImage = None
def image_lib_link(lib=None):
if not lib:
lib = 'gd' if gdImage else 'pil'
name, src = dict(
gd=('GD module', 'newcenturycomputers.net/projects/gdmodule.html'),
pil=('Pillow library', 'pypi.org/project/Pillow/'))[lib]
return '<a href="https://%s">%s</a>' % (src, name)
X, Y = 500, 200 # the image size
def t(p):
"""Map coordinates: (x=0..2pi, y=-1.25..1.25) => (0..X, Y..0)"""
return int(.5*X*p[0]/pi+.5), int(.4*Y*(1.25- p[1])+.5)
colors = (255, 255, 255), (0, 0, 0), (0, 0, 255), (255, 0, 0)
white, black, blue, red = range(4)
class Drawing(object):
"""Simple wrapper class for drawing the example image."""
if gdImage:
def __init__(self):
self._image = gdImage((X, Y))
self._color = map(self._image.colorAllocate, colors)
self._font = gdFontLarge
def text(self, pos, string, color):
color = self._color[color]
self._image.string(self._font, t(pos), string, color)
def lines(self, points, color):
color = self._color[color]
self._image.lines(map(t, points), color)
def png(self):
s = StringIO()
self._image.writePng(s)
return s.getvalue()
else:
def __init__(self):
self._image = pilImage.new('RGB', (X, Y), colors[white])
self._draw = ImageDraw.Draw(self._image)
for font in 'Tahoma Verdana Arial Helvetica'.split():
try:
font = ImageFont.truetype(font + '.ttf', 12)
except (AttributeError, IOError):
font = None
if font:
break
else:
try:
font = ImageFont.load_default()
except (AttributeError, IOError):
font = None
self._font = font
def text(self, pos, string, color):
color = colors[color]
self._draw.text(t(pos), string, color, font=self._font)
def lines(self, points, color):
color = colors[color]
self._draw.line(map(t, points), color)
def png(self):
s = StringIO()
self._image.save(s, 'png')
return s.getvalue()
class ImageDemo(ExamplePage):
"""Dynamic image generation example.
This example creates an image of a sinusoid.
For more information on generating graphics, see
https://wiki.python.org/moin/GraphicsAndImages.
This example works with both Pillow and GD.
"""
saveToFile = False
def defaultAction(self):
fmt = self.request().field('fmt', None)
if fmt == '.png' and (gdImage or pilImage):
image = self.generatePNGImage()
res = self.response()
res.setHeader("Content-Type", "image/png")
res.setHeader("Content-Length", str(len(image)))
if self.saveToFile:
res.setHeader("Content-Disposition",
"attachment; filename=demo.png")
self.write(image)
else:
self.writeHTML()
def writeContent(self):
wr = self.writeln
wr('<h2>WebKit Image Generation Demo</h2>')
if gdImage or pilImage:
wr('<img src="ImageDemo?fmt=.png" alt="Generated example image"'
' width="%d" height="%d">' % (X, Y))
wr('<p>This image has just been generated using the %s.</p>' %
image_lib_link())
else:
wr('<h4 style="color:red">Sorry: No image library available.</h4>')
wr('<p>This example requires the %s.</p>' % ' or the '.join(
map(image_lib_link, ('gd', 'pil'))))
def generatePNGImage(self):
"""Generate and return a PNG example image."""
def f(x):
return x, sin(x)
draw = Drawing()
draw.text((2.7, 0.8), 'y=sin(x)', black)
draw.text((0.2, -0.8), 'created: ' + asclocaltime(), red)
draw.lines(((0, 0), (2*pi, 0)), black) # x-axis
draw.lines(((0, -1), (0, 1)), black) # y-axis
draw.lines(map(f, map(lambda x: x*2*pi/X, xrange(X+1))), blue)
return draw.png()