#43 pyx draws bitmaps incorrectly


Running the following script should produce a series of
blocks of the 256 shades of grey between and including
black and white.

import pyx
pbb = pyx.bitmap.bitmap
pbi = pyx.bitmap.image
c = pyx.canvas.canvas()
for i in xrange(256):
c.insert(pbb(.5(i&15), .5(i>>4),
pbi(10,10,"L",100*chr(i)), height=.5))

Instead, it produces either an all-white or all-black
image at random. This is the case when using Windows
2000, Python 2.3 and 2.4, and is verifiable in both
Adobe Acrobat 7 and Foxit Reader 1.3 . Adjusting the
above code as necessary for RGB images does not fix the

The problem exists for the two most recent versions of PyX.


  • Josiah Carlson

    Josiah Carlson - 2006-06-22

    Logged In: YES

    A work-around is to create a temporary canvas, insert the
    image into the temporary canvas, and insert the temporary
    canvas into the main canvas.

  • Jörg Lehmann

    Jörg Lehmann - 2006-06-23

    Logged In: YES

    Hello Josiah,

    thanks for your bug report. This bug has already been
    fixed in SVN (revision 2825). The fix is a one-liner:

    Index: pyx/bitmap.py

    --- pyx/bitmap.py (Revision 2824)
    +++ pyx/bitmap.py (Revision 2825)
    @@ -259,6 +259,9 @@
    PSstoreimage=0, PSmaxstrlen=4093,
    dctquality=75, dctoptimize=0,
    + # keep a copy of the image instance to ensure
    different id's
    + self.image = image
    self.xpos = xpos
    self.ypos = ypos
    self.imagewidth, self.imageheight = image.size

    I'm marking this bug as fixed and closing it.

  • Andre Wobst

    Andre Wobst - 2006-06-23

    Logged In: YES

    Let me add another short comment although the report was already answered
    and closed.

    The real problem is, that PyX uses the id of the image object to generate a
    unique number of the image to be drawn. The idea is to make it possible to
    reuse the same image resource several times and have the image included
    only once in the output. This works automatically in PDF, since there is such a
    image object by default. In PostScript this can be done as well and PyX
    supports this, but you need to use memory (it might be a lot of memory) on
    the PostScript interpreter, since PostScript is a "get a stream and immediately
    execute it" language.

    And your problem is related to the fact, that the garbage collector collects the
    image instance as soon as it's not refered anymore and then the other image
    instance reuses the memory and thus has the same id. While we have fixed
    this in PyX resently (after a stepped into the problem myself last weekend),
    you can also work around easily on old PyX versions by just ensuring, that the
    garbage collector does not collect the image instances as long as you create
    other instances. (The id of the image instance is calculated during the
    constructor of the bitmap instance.) So a workaround for your code without
    changing the PyX core would be:

    import pyx
    pbb = pyx.bitmap.bitmap
    pbi = pyx.bitmap.image
    c = pyx.canvas.canvas()
    images = []
    for i in xrange(256):
    image = pbi(10,10,"L",100chr(i))
    (i&15), .5*(i>>4), image, height=.5))

    Best, André


Log in to post a comment.