--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/logo.py Tue May 05 16:21:41 2009 +0300
@@ -0,0 +1,173 @@
+#!/usr/bin/python2.5
+import cgi, cgitb
+
+cgitb.enable()
+
+from PIL import Image, ImageDraw, ImageFont
+from cStringIO import StringIO
+import random
+
+
+# settings
+text = [
+ "aalto",
+ "unive",
+ "rsity"
+]
+
+random_chars = [ '"', '!', '?' ]
+
+line_colors = [
+ "#0469af",
+ "#fbc614",
+ "#e1313b",
+]
+
+fonts = {
+ 'dejavu-sans-bold': "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf",
+ 'helvetica': "HELR65W.TTF",
+}
+
+font_name = 'helvetica'
+font_size = 30
+
+def randomize (seq) :
+ """
+ Returns the given sequence in random order as a list
+ """
+
+ # copy
+ l = list(seq)
+
+ # rearrange
+ random.shuffle(l)
+
+ return l
+
+def build_data (text, chars, line_colors) :
+ """
+ Returns a matrix of (text, color) tuples representing the data to render
+
+ [ [ (str, str) ] ]
+
+ text - list of lines
+ chars - list of random chars to interpse
+ line_colors - list of colors to draw the chars in
+ """
+
+ data = []
+
+ for line, char, color in zip(text, chars, line_colors) :
+ # pick position to place char
+ pos = random.randint(1, len(line) - 1)
+
+ # split into three parts
+ data.append([
+ (line[:pos], "#000000"),
+ (char, color),
+ (line[pos:], "#000000"),
+ ])
+
+ return data
+
+def load_font (font_name, font_size) :
+ """
+ Load a font by name
+ """
+
+ # load font
+ font_path = fonts[font_name]
+ font = ImageFont.truetype(font_path, font_size)
+
+ return font
+
+def render_img (data, font, background_color="#ffffff", line_spacing=0) :
+ """
+ Render the data (as from build_data) as an image, using the given PIL.ImageFont, and return the PIL Image object
+ """
+
+ img_width = img_height = 0
+
+ img_data = []
+
+ # compute image width/height
+ for segments in data :
+ line_width = line_height = 0
+
+ # build a new list of segments with additional info
+ line_segments = []
+
+ for seg_text, seg_color in segments :
+ # compute rendered text size
+ seg_width, seg_height = font.getsize(seg_text)
+
+ # update line_*
+ line_width += seg_width
+ line_height = max(line_height, seg_height)
+
+ # build the new segments list
+ line_segments.append((seg_text, seg_color, seg_width))
+
+ # update img_*
+ img_width = max(img_width, line_width)
+ img_height += line_height
+ img_data.append((line_segments, line_height))
+
+ # calculate height needed for line spacing
+ img_height += (len(img_data) - 1) * line_spacing
+
+ # create image
+ img = Image.new("RGB", (img_width, img_height), background_color)
+ draw = ImageDraw.Draw(img)
+
+ # draw text
+ img_y = 0
+ for segments, line_height in img_data :
+ img_x = 0
+
+ # draw each segment build above, incremeing along img_x
+ for seg_text, seg_color, seg_width in segments :
+ draw.text((img_x, img_y), seg_text, font=font, fill=seg_color)
+
+ img_x += seg_width
+
+ img_y += line_height + line_spacing
+
+ return img
+
+def build_png (img) :
+ """
+ Write the given PIL.Image as a string, returning the raw binary data
+ """
+
+ # render PNG output
+ buf = StringIO()
+ img.save(buf, "png")
+ data = buf.getvalue()
+
+ return data
+
+def response (type, data) :
+ """
+ Write out the HTTP Response
+ """
+
+ from sys import stdout
+
+ stdout.write("Content-Type: %s\r\n" % type)
+ stdout.write("Content-Length: %d\r\n" % len(data))
+ stdout.write("\r\n")
+ stdout.write(data)
+
+def main () :
+ data = build_data(text, randomize(random_chars), line_colors)
+ font = load_font(font_name, font_size)
+
+ img = render_img(data, font)
+ png_data = build_png(img)
+
+ response("image/png", png_data)
+
+if __name__ == '__main__' :
+ main()
+