[Zope] Create image with PIL in Zope

Jonathan Hobbs toolkit at magma.ca
Fri Oct 1 10:38:05 EDT 2004


From: "Bruno Miguel Silva" <bruno at techwave.org>
>     I have a small script that generate a image with some text, in python
with
> Python Imagin Library (PIL).
>    The problem is, i want a security image in an html page in zope, so i
> started to put the code in a External module, and now i have all kind of
> problems with that script.
>    When i use the "ImageFont.load('pathToFont.pil')", that causes an
> Error Type: IOError
> Error Value: cannot find glyph data file
>    i don' understand, because i have the ".pbm", and it works in command
line.
>
>    So, then i try to do "ImageFont.load_path('font.pil')", and that causes
a
> Error Type: IOError
> Error Value: cannot find font file
>    once again i couldn't understand because it works on command line,
because
> the font file is in "/usr/lib/python2.3/site-packages/pilfonts/"
>
>    At this time, i start to dig in the sourcecode of ImageFont.py, and i
found
> that when it raises the "cannot find glyph data file", is when it try's to
> open the ".pbm" file with Image.open(), i tried to do this to get more
> information, and it gives a
> Error Type: AttributeError
> Error Value: 'file' object has no attribute 'startswith'
>
>    I don't know if this makes any sense to you, .... but are there someone
to
> help me in this?
>    Do i have other alternatives to generate images with text on the fly in
> zope?

I don't know what the cause of your PIL problem is, but here are some code
chunks from routines that we use to generate images on the fly that may give
you some clues:

1) Code from  dtml method that gathers info from a form and db then calls an
external method to generate the images, then displays the images:

  <dtml-comment> build graph for daily qty & percentage chart
</dtml-comment>

  <dtml-call "REQUEST.set('ts', ZopeTime())">
  <dtml-with TmpImages>
    <dtml-call "REQUEST.set('graphtype', 'day_qty_percent')">
    <dtml-let  tt="graphics(REQUEST)">
      <dtml-call "REQUEST.set('day_qty_percent_id',_.str(_.int(ts)))">
      <dtml-call "this().manage_addImage(day_qty_percent_id, tt)">
    </dtml-let>
  </dtml-with>

  <dtml-comment> display graph (previously created/store in TmpImages
folder) for daily qty & percentages </dtml-omment>

  <center>
   <br>
   <img src="TmpImages/&dtml-day_qty_percent_id;">
  </center>


2) Code from the external method which generates the images

from piddlePIL import *

class RamFile:
                def __init__(self):
                        self.contents = []
                def write(self,s):
                        self.contents.append(s)
                def read(self):
                        return string.join(self.contents,'')

class Colour:
                dark = HexColor("D0DDAD")
                light = HexColor("EBFFD9")

def graphics(REQUEST):
        datalist = REQUEST.get('datalist')
        graphtype = REQUEST.get('graphtype')

        if graphtype == 'day_qty_percent':
                return day_qty_percent(datalist)


def day_qty_percent(datalist):

        import fpformat

        canvas = PILCanvas()
        canvas.drawRect( 0,0,300,300, fillColor=Colour.light )
        canvas.drawRect( 2,2,296,297, edgeColor=Colour.dark, edgeWidth=5 )

        totalcount = 0
        biggestday = 0
        for today in datalist:
                totalcount = totalcount + today
                if today > biggestday:
                        biggestday = today

        scale = 150.0/((float(biggestday)/float(totalcount))*100.0)

        i = 0
        for x in datalist:
                xpercent = (float(x)/float(totalcount)) * 100.0
                x1 = int(xpercent * scale)
                if x > 0:
                        canvas.drawRect(23, 40+(i*35), x1+23,
60+(i*35),fillColor=Colour.dark)
                xstr = str(int(x))
                canvas.drawString(xstr, x1+28, 53+(i*35),
Font(face="times",size=14,bold=0), color=black, angle=0)
                canvas.drawString("("+str(fpformat.fix(xpercent,1))+"%)",
x1+38+(len(xstr)*6), 53+(i*35) ,Font(face="times",size=12,bold=0), $
                i = i + 1

        canvas.drawString("Parking Events  (Total
"+str(int(totalcount))+")", 50, 19, Font(face="times",size=12,bold=1),
color=black, angle=0)
        canvas.drawLine(22, 25, 22, 293, color=slategray)
        canvas.drawString("M", 7,53, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("T", 7,88, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("W", 7,123, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("T", 7,158, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("F", 7,193, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("S", 7,228, Font(face="times",size=14,bold=1),
color=black, angle=0)
        canvas.drawString("S", 7,263, Font(face="times",size=14,bold=1),
color=black, angle=0)

        canvas.flush()

        rfile = RamFile()
        canvas.save(file=rfile,format="jpeg")
        return rfile.read()



HTH

Jonathan




More information about the Zope mailing list