log_formatter_pil.py
author Tero Marttila <terom@fixme.fi>
Sun, 15 Feb 2009 23:50:24 +0200
changeset 129 67a30d680f60
parent 124 4bc4de14f006
permissions -rw-r--r--
Autodetect user timezone using Javascript, this makes the Preferences code a bit more complicated in terms of interaction between default/parse/is_default/build/process/etc, but it should work as intended now
"""
    Use of PIL to render the image formatting stuff
"""

from PIL import Image, ImageDraw, ImageFont

from cStringIO import StringIO

class PILImageFormatter (object) :
    """
        Mixin for LogFormatter that implements the basic image-rendering operations on top of format_txt
    """
    
    # the font we load
    font = None

    # line spacing in pixels
    LINE_SPACING = 1

    def _load_font (self) :
        """
            Use the configured img_ttf_path for a TrueType font, or a default one
        """

        if self.font :
            pass
        
        elif self.img_ttf_path :
            # load truetype with configured size
            self.font = ImageFont.truetype(self.img_ttf_path, self.img_font_size)

        else :
            # default
            self.font = ImageFont.load_default()

        return self.font

    def format_png (self, lines, **kwargs) :
        """
            Build and return a PNG image of the given lines, using format_txt
        """

        # load font
        font = self._load_font()

        # build list of plain-text line data
        lines = list(data for line, data in self.format_txt(lines, **kwargs))
        
        # lines sizes
        line_sizes = [font.getsize(line) for line in lines]

        # figure out how wide/high the image will be
        width = max(width for width, height in line_sizes)
        height = sum(height + self.LINE_SPACING for width, height in line_sizes)

        # create new B/W image
        img = Image.new('L', (width, height), 0xff)

        # drawer
        draw = ImageDraw.Draw(img)
        
        # starting offset
        offset_y = 0

        # draw the lines
        for line, (width, height) in zip(lines, line_sizes) :
            # draw
            draw.text((0, offset_y), line, font=font)

            # next offset
            offset_y += height + self.LINE_SPACING
        
        # output buffer
        buf = StringIO()

        # save
        img.save(buf, 'png')

        # return data
        return buf.getvalue()