Palette-mode PNG images

Lawrence D'Oliveiro ldo at geek-central.gen.new_zealand
Sun Nov 16 07:19:07 CET 2008


I'm trying to create PNG files to use in menus for authoring DVDs. As you
may know, these menus are only allowed to have limited numbers of colours.

Ideally I'd like to create a PNG file with just two bits per pixel, with
four colour-table entries of my choice. I'm using PyCairo
<http://www.cairographics.org/pycairo/> to do the drawing, but that doesn't
seem to support colour-table images as far as I can tell. So I'm trying to
figure out how to use PIL
<http://www.pythonware.com/library/pil/handbook/index.htm> to save the
images to PNG files with a suitable format.

However, it looks like PIL wants 256 colour-table entries. When I try to
pass fewer, e.g.

    ThePix = array.array("B", '\0' * ImageWidth * ImageHeight * 4)
    ThePixSurface = cairo.ImageSurface.create_for_data(ThePix,
        cairo.FORMAT_ARGB32, ImageWidth, ImageHeight, ImageWidth * 4)
      # can't find format_stride_for_width?
    TheDraw = cairo.Context(ThePixSurface)
    ...
    ThePixSurface.flush() # prior to writing out pixels myself
    TheImage = Image.frombuffer("RGBA", (ImageWidth, ImageHeight),
         ThePix, "raw", "RGBA", 0, 1)
    TheImage = TheImage.convert("P")
    TheImage.putpalette([(0, 0, 0), (255, 255, 255), (0, 255, 0),
        (0, 255, 255)])
    TheImage.save("png_palette_test.png")

it dies with the following, on the putpalette line:

    Traceback (most recent call last):
      File "./png_palette_test", line 41, in <module>
        TheImage.putpalette([(0, 0, 0), (255, 255, 255), (0, 255, 0),
            (0, 255, 255)])
      File "/usr/lib64/python2.5/site-packages/PIL/Image.py", line 1205,
          in putpalette
          data = string.join(map(chr, data), "")
      TypeError: an integer is required

Cairo also supports FORMAT_A8 and FORMAT_A1 images--should I be using the
latter, perhaps?

Also I see that the PIL PNG encoder/decoder supports a "bits" output option
<http://www.pythonware.com/library/pil/handbook/format-png.htm> which is
marked as "experimental". Can this be useful for constraining the pixel
depth of the output image?

Thanks for any suggestions.



More information about the Python-list mailing list