Search code examples
pythonpngcairopycairo

white flashes on transparent image edges in cairo


I am trying to display png image with transparency on black background, moving it slowly around on surface, but a lot of frames contain white pixels. (that should not be there at all)

white pixel on wikimedia logo

The logo surface is created like this:

self.logo_surface = cairo.ImageSurface.create_from_png(image)

And every frame is drawn like this: I move it to a new position and then scale image down to 15x15px

def draw(self, ctx):
    # scale image and move it to a right place
    ctx.save()
    ctx.translate(self.left, self.top)
    ctx.scale(self.scale_xy, self.scale_xy)
    ctx.set_source_surface(self.logo_surface)

    #Here i tried different filters but without improvement in reducing white flashes
    ctx.get_source().set_filter(cairo.FILTER_FAST)

    ctx.paint()
    ctx.restore()

left, top, scale_xy are float. Left and top are changed a bit every frame.

How could i prevent those flashes?

EDIT:

1)The data from the final surface is extracted using get_data.

buf = self.surface.get_data()
a = numpy.frombuffer(buf, numpy.uint8)

2)This effect does not happen when translate is given integer values:

ctx.translate(int(self.left), int(self.top))

but then the image does not move smoothly anymore on 100x100px surface


Solution

  • The wikimedia logo contained some white pixels between transparent and colored part. Because it is a big picture it cannot be seen unless zoomed very close. If downscaled with cairo, it sometimes happened to use those "white" pixel values - hence flashing white pixels on the image.