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)

ButtonMaker (last edited 2008-03-04 08:33:03 by localhost)