This script makes PNG buttons. It requires the GD drawing library, the gd Python module, and some TrueType fonts. It only makes square buttons with the corner cut out- no bevels or curved corners, but it could be made to do this pretty easily. --AdamFeuer
# !/usr/bin/env python
#
# cgi script to make PNG buttons
#
# Copyright 2001 Adam Feuer (adamf@pobox.com)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# (very simple buttons for now- just rectangles with one pixel cut out.)
# (rounded and square corners coming soon...)
#
import sys,getopt
import os,os.path,stat
import random
import cgi, urllib
import gd
VERSION = "0.2"
# how much of the PNG images to read at one time
BUFSIZE = 100000
# where to put the truetype fonts
FONTDIR = "fonts"
DEFAULT_TEXT = "Default"
DEFAULT_FILENAME = "/tmp/button.png"
DEFAULT_FONT = "arial"
DEFAULT_FONTSIZE = 8.0
DEFAULT_FONTCOLOR = (0,0,0) # black
DEFAULT_BGCOLOR = (255,255,255) # white
DEFAULT_PADDING = 4
def random_filename(prefix="/tmp",suffix=".png"):
"""return a random filename that does not exist on the filesystem-"""
while 1:
n = random.randrange(0,1000000000)
filename = "%s/button%d%s" %(prefix,n,suffix)
if not os.path.exists(filename):
break
return filename
# convert hex color triple to decimal
def get_rgb_triple(colorstring):
"""convert hex color triple to decimal-
takes a string of format 'FFFFFF' where F is hex digit"""
if len(colorstring) != 6:
# bad color string
return None
else:
#print colorstring
r = eval("0x%s" % colorstring[0:2])
g = eval("0x%s" % colorstring[2:4])
b = eval("0x%s" % colorstring[4:])
#print r,g,b
return [r,g,b]
def make_button(button_text,font,button_fontsize,button_pad,fontcolor,bgcolor,button_filename):
""" make a PNG button using the specified parameters.
Saves the PNG image to the file specified by button_filename"""
if font[-4:] != '.ttf':
fontttf = "%s.ttf" % font
button_font = os.path.join(FONTDIR,fontttf)
im0 = gd.image((200, 200))
# bounding rect
br = im0.get_bounding_rect(button_font,button_fontsize,0.0,(0,0),button_text)
x1 = br[6]
y1 = br[7]
x2 = br[2]
y2 = br[3]
width = x2 - x1
height = y2 - y1
#print "text w: %d h: %d" % (width,height)
rw = width + button_pad*2 + 1
rh = height + button_pad*2 + 1 + 2
#print "button rw: %d rh: %d" % (rw,rh)
im1 = gd.image((rw,rh))
button_fontcolor = im1.colorAllocate(fontcolor)
button_bgcolor = im1.colorAllocate(bgcolor)
t = [0,0,0]
for loop in range(0,3):
t[loop] = (fontcolor[loop] + bgcolor[loop]+2) % 256
#print "transparent: %s" % t
transparent = im1.colorAllocate(t)
im1.colorTransparent(transparent)
im1.interlace(1)
rx1,ry1 = 0,0
rx2,ry2 = rw-1,rh-1
# font starts drawing in lower left corner
sx1 = rx1 + button_pad
sy1 = ry1 + height + button_pad
#print "rxy1: %d,%d rxy2: %d,%d" % (rx1,ry1,rx2,ry2)
#print "sxy1: %d,%d" % (sx1,sy1)
im1.filledRectangle((rx1,ry1),(rx2,ry2),button_bgcolor)
im1.string_ttf(button_font, button_fontsize, 0.0, (sx1,sy1), button_text, button_fontcolor)
# draw outline
im1.line((rx1,ry1),(rx2,ry1),button_fontcolor)
im1.line((rx1,ry2),(rx2,ry2),button_fontcolor)
im1.line((rx2,ry1),(rx2,ry2),button_fontcolor)
im1.line((rx1,ry1),(rx1,ry2),button_fontcolor)
im1.setPixel((rx1,ry1),transparent)
im1.setPixel((rx1,ry2),transparent)
im1.setPixel((rx2,ry1),transparent)
im1.setPixel((rx2,ry2),transparent)
f=open(button_filename,"w")
im1.writePng(f)
f.close()
return 1
if __name__ == "__main__":
#cgi.test()
#raise SystemExit
# defaults
text = DEFAULT_TEXT
filename = DEFAULT_FILENAME
font = DEFAULT_FONT
fontsize = DEFAULT_FONTSIZE
padding = DEFAULT_PADDING
fontcolor = DEFAULT_FONTCOLOR
bgcolor = DEFAULT_BGCOLOR
form = cgi.FieldStorage()
if form.has_key("text"):
text = urllib.unquote(form["text"].value)
if form.has_key("font"):
font = urllib.unquote(form["font"].value)
if form.has_key("fontsize"):
fontsize = float(form["fontsize"].value)
if form.has_key("padding"):
padding = int(form["padding"].value)
if form.has_key("fontcolor"):
fontcolor = get_rgb_triple(form["fontcolor"].value)
if form.has_key("bgcolor"):
bgcolor = get_rgb_triple(form["bgcolor"].value)
#print "text: %s file: %s fontsize: %s fontcolor: %s bgcolor: %s padding: %s" % (text,filename,fontsize,fontcolor,bgcolor,padding)
filename = random_filename()
make_button(text,font,fontsize,padding,fontcolor,bgcolor,filename)
print "Content-type: image/png"
statinfo = os.stat(filename)
size = statinfo[stat.ST_SIZE]
# print "Content-length: %d" % size
print
f = open(filename,'r')
s = f.read(BUFSIZE)
while s != "":
sys.stdout.write(s)
s = f.read(BUFSIZE)
f.close()
os.remove(filename)