whi
whi

Reputation: 2750

How to speed up drawing many circles in Python PIL

In python PIL lib, I'm using

>>> draw.ellipse((x - r, y - r, x + r, y + r))  

to draw circle as nodes. However, since there are thousands of nodes to draw, this takes too long.
Is there faster way to draw all my nodes?

For background: to draw a tree-like graph, with circles as nodes.

Upvotes: 2

Views: 1730

Answers (2)

whi
whi

Reputation: 2750

I found image.paste() improve speed to about 5 times. there's a transparent problem to avoid overlapping, so mask make speed a little slower.

def init_circle(r):
    center = [r] * 2
    im = Image.new(IMG_MODE, [r * 2] * 2, FG_COLOR)
    draw = ImageDraw.Draw(im) 
    draw.setink(BG_COLOR)
    draw.ellipse((1, 1, r * 2 - 1, r * 2 - 1), fill=NODE_COLOR)
    mask = invert(im.convert('L'))
    return im.crop((0, 0) + (r * 2, r * 2)), mask

to use it:

im.paste(circle, (x, y, x + 2 * r, y + 2 * r), mask=mask)

Upvotes: 2

invert
invert

Reputation: 2076

If you draw that many ellipses every cycle it will be slow.

Is there a specific reason you need to use PIL? From your question details, I am not sure PIL is suited for your task: you need a graphics library, not an image manipulation library. There is a difference.

PyGame is a SDL wrapper suited for high performance drawing routines.

Some tricks include drawing to a surface once, and then only redrawing dirty regions. A tutorial of this can be found here:

Most people new to graphics programming use the first option - they update the whole screen every frame. The problem is that this is unacceptably slow for most people.

The solution is called 'dirty rect animation'. Instead of updating the whole screen every frame, only the parts that changed since the last frame are updated.

Upvotes: 5

Related Questions