Search code examples
pythonimageplotdrawing

Faster way to plot an image with PIL?


I have a set of (x,y) coordinates rasterized from a sketch:

x = [167, 109, 80, 69, 58, 31]
y = [140, 194, 227, 232, 229, 229]

I want to recreate that sketch and save it as an image. At the moment I am using PIL draw line function, like this:

from PIL import Image, ImageDraw

im = Image.new('L', (256, 256), 255)
draw = ImageDraw.Draw(im)
for i in range(len(x)-1):
    draw.line((x[i],y[i], x[i+1], y[i+1]),fill=0,width=2)
im.save('test.png')

output

I wonder if there is a faster way to do it. The (x,y) points are in drawing order, so maybe using Image.putdata() could help?


Solution

  • This more-or-less demonstrates what I was suggesting in the comments (sans the * prefix on the zip() call) about being able to draw the entire line using only one call to draw.line().

    The advantages are it'll take less code and might be slightly faster (even if that's not noticeable with the test data).

    try:
        from itertools import izip
    except ImportError:  # Python 3
        izip = zip
    from PIL import Image, ImageDraw
    
    x = [167, 109, 80, 69, 58, 31]
    y = [140, 194, 227, 232, 229, 229]
    
    im = Image.new('L', (256, 256), 255)
    draw = ImageDraw.Draw(im)
    
    #for i in range(len(x)-1):
    #    draw.line((x[i],y[i], x[i+1], y[i+1]), fill=0, width=2)
    
    draw.line(list(izip(x, y)), fill=0, width=2) # Draws entire line.
    #im.save('test.png')
    im.show()  # Display the image.