2017-10-06 3 views
1

I einen Satz (x, y) haben Koordinaten von einer Skizze gerasterten:Schneller Weg, um ein Bild mit PIL zu plotten?

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

Ich will diese Skizze erstellen, und es als ein Bild zu speichern. Im Moment bin ich mit PIL Zuglinie Funktion, wie folgt aus:

from PIL import Image, ImageDraw 
img = [[1, 1]] 
im = Image.new('L', (256, 256), 255) 
imgdata = np.array(img[0][1])*256 + np.array(img[0][1]) 
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

Ich frage mich, ob es einen schnelleren Weg, es zu tun ist. Die (x, y) Punkte sind in Zeichnungsreihenfolge, also könnte vielleicht die Verwendung von Image.putdata() helfen?

+0

'Image.putdata()' würden Sie benötigen, um die Pixeldaten durch andere Mittel zu erstellen und sie dann stopfen in eine 'Image' objekt, die ich dir, es sei denn tun wollen zweifeln Sie können ein vorhandenes Modul finden, um es zu tun (zeichnen Sie die Linie). Sie machen es mit dem PIL so schnell wie möglich. – martineau

+1

Beachten Sie jedoch, dass [ImageDraw.line() '] (http://pillow.readthedocs.io/en/4.3.x/reference/ImageDraw.html#PIL.ImageDraw.PIL.ImageDraw.ImageDraw.line) akzeptiert wird _all_ die Koordinaten in einem einzigen Aufruf, so dass Sie die 'for'-Schleife entfernen und zumindest eine gewisse Geschwindigkeitsverbesserung erzielen können. – martineau

+1

Befreien Sie sich von der 'for' -Schleife und versuchen Sie es mit einem einzelnen' draw.line (* zip (x, y), fill = 0, width = 2) 'Anruf. – martineau

Antwort

1

Diese mehr oder weniger zeigt, was ich in den Kommentaren wurde darauf hindeutet (sans den * Präfix auf den zip() Anruf) über die Möglichkeit, die gesamte Linie mit nur einem Anruf draw.line() zu ziehen.

Die Vorteile sind, dass es weniger Code braucht und wahrscheinlich etwas schneller ist (auch wenn es mit den Testdaten nicht auffällt).

import numpy as np 
from PIL import Image, ImageDraw 

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

im = Image.new('L', (256, 256), 255) 
imgdata = np.array(img[0][1])*256 + np.array(img[0][1]) 
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(zip(x, y), fill=0, width=2) # Draws entire line. 
#im.save('test.png') 
im.show() # Display the image. 

Für Python 3.x Sie bräuchten die Linie zip() auf die folgende Verwendung ändern (die, während es wäre in Ordnung 2 in Python zu tun, extra nach sich ziehen würde, obwohl harmlos, Verarbeitung, die nicht notwendig) ist:

draw.line(list(zip(x, y)), fill=0, width=2) # Draws entire line. 
Verwandte Themen