We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Drawing WCK Graphics in a PIL Image Memory

December 7, 2003 | Fredrik Lundh

This class implements a WCK-style drawing interface on top of a PIL Image memory.

A similar module will most likely be added to a future version of PIL.

from PIL import ImageColor, ImageDraw, ImagePath

class Pen:
    def __init__(self, color, width=1):
        self.color = ImageColor.getrgb(color)
        self.width = width

class Brush:
    def __init__(self, color):
        self.color = ImageColor.getrgb(color)

class SimpleDraw:

    def __init__(self, image):
        self.draw = ImageDraw.Draw(image)
        self.transform = None

    def render(self, op, xy, pen, brush):
        # handle color arguments
        outline = fill = None
        if isinstance(pen, Pen):
            outline = pen.color
        elif isinstance(brush, Pen):
            outline = brush.color
        if isinstance(brush, Brush):
            fill = brush.color
        elif isinstance(pen, Brush):
            fill = pen.color
        # handle transformation
        if self.transform:
            xy = ImagePath.Path(xy)
            xy.transform(self.transform)
        # render the item
        if op == "line":
            self.draw.line(xy, fill=outline)
        else:
            getattr(self.draw, op)(xy, fill=fill, outline=outline)

    def settransform(self, (xoffset, yoffset)):
        self.transform = (1, 0, xoffset, 0, 1, yoffset)

    def line(self, xy, pen=None):
        self.render("line", xy, pen, None)

    def rectangle(self, xy, pen=None, brush=None):
        self.render("rectangle", xy, pen, brush)

    def ellipse(self, xy, pen=None, brush=None):
        self.render("ellipse", xy, pen, brush)

    def polygon(self, xy, pen=None, brush=None):
        self.render("polygon", xy, pen, brush)

Notes:

The PIL drawing layer doesn’t support wide lines.

Text support is not included in this example; adding that should be straightforward.

The settransform method only supports translation.