web-dev-qa-db-fra.com

Comment convertir le contenu du canevas en image?

from Tkinter import *
root = Tk()
cv = Canvas(root)
cv.create_rectangle(10,10,50,50)
cv.pack()
root.mainloop()

Je souhaite convertir le contenu du canevas en bitmap ou autre image, puis effectuer d'autres opérations, telles que la rotation ou la mise à l'échelle de l'image, ou la modification de ses coordonnées.

Les bitmaps peuvent améliorer l'efficacité pour montrer si je ne dessine plus.

Que devrais-je faire?

19
liupeixin

Vous pouvez soit générer un document postscript (pour alimenter un autre outil: ImageMagick, Ghostscript, etc.):

from Tkinter import *
root = Tk()
cv = Canvas(root)
cv.create_rectangle(10,10,50,50)
cv.pack()
root.mainloop()

cv.update()
cv.postscript(file="file_name.ps", colormode='color')

root.mainloop()

ou dessinez la même image en parallèle sur PIL et sur le canevas de Tkinter (voir: Enregistrer un dessin de canevas Tkinter (Python) ). Par exemple (inspiré du même article):

from Tkinter import *
import Image, ImageDraw

width = 400
height = 300
center = height//2
white = (255, 255, 255)
green = (0,128,0)

root = Tk()

# Tkinter create a canvas to draw on
cv = Canvas(root, width=width, height=height, bg='white')
cv.pack()

# PIL create an empty image and draw object to draw on
# memory only, not visible
image1 = Image.new("RGB", (width, height), white)
draw = ImageDraw.Draw(image1)

# do the Tkinter canvas drawings (visible)
cv.create_line([0, center, width, center], fill='green')

# do the PIL image/draw (in memory) drawings
draw.line([0, center, width, center], green)

# PIL image can be saved as .png .jpg .gif or .bmp file (among others)
filename = "my_drawing.jpg"
image1.save(filename)

root.mainloop()
22
Nif

J'ai trouvé un excellent moyen de le faire, ce qui est vraiment utile. Pour cela, vous avez besoin du module PIL. Voici le code:

from PIL import ImageGrab

def getter(widget):
    x=root.winfo_rootx()+widget.winfo_x()
    y=root.winfo_rooty()+widget.winfo_y()
    x1=x+widget.winfo_width()
    y1=y+widget.winfo_height()
    ImageGrab.grab().crop((x,y,x1,y1)).save("file path here")

Cela signifie que vous passez un nom de widget dans la fonction. Les commandes root.winfo_rootx() et root.winfo_rooty() obtiennent la position des pixels en haut à gauche de la fenêtre globale root.

Ensuite, les widget.winfo_x() et widget.winfo_y() sont ajoutées à, en gros il suffit d'obtenir les coordonnées en pixels du pixel supérieur gauche du widget que vous souhaitez capturer (en pixels (x, y) de votre écran).

Je trouve ensuite le (x1, y1) qui est le pixel inférieur gauche du widget. La ImageGrab.grab() crée un écran d'impression, puis je le recadre pour obtenir uniquement le bit contenant le widget. Bien qu'il ne soit pas parfait et ne produise pas la meilleure image possible, il s'agit d'un excellent outil pour simplement obtenir une image d'un widget et l'enregistrer.

Si vous avez des questions, postez un commentaire! J'espère que cela vous a aidé!

18
B.Jenkins

Utilisez Pillow pour convertir de Postscript en PNG

from PIL import Image

def save_as_png(canvas,fileName):
    # save postscipt image 
    canvas.postscript(file = fileName + '.eps') 
    # use PIL to convert to PNG 
    img = Image.open(fileName + '.eps') 
    img.save(fileName + '.png', 'png') 
1
Andy Richter

Vous pouvez peut-être essayer d'utiliser widget_winfo_id pour obtenir le HWND du canevas.

import win32gui

from PIL import ImageGrab

HWND = canvas.winfo_id()  # get the handle of the canvas

rect = win32gui.GetWindowRect(HWND)  # get the coordinate of the canvas

im = ImageGrab.grab(rect)  # get image of the current location
0
Vincent Zhang