Как преобразовать содержимое холста в изображение?

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

Я хочу преобразовать содержимое холста в растровое изображение или другое изображение, а затем выполнять другие операции, такие как вращение или масштабирование изображения или изменение его координат.

Растровые изображения могут повысить эффективность, чтобы показать, если я больше не рисую.

Что мне делать?

Ответ 1

Вы можете либо сгенерировать документ postscript (для подачи на другой инструмент: ImageMagick, Ghostscript и т.д.):

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()

или нарисуйте одно и то же изображение параллельно на PIL и на холсте Tkinter (см. Сохранение рисунка холста Tkinter (Python)). Например (вдохновленный той же статьей):

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()

Ответ 2

Я нашел отличный способ сделать это, что очень полезно. Для этого вам нужен модуль PIL. Вот код:

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")

Что это значит, вы передаете имя виджета в функцию. Команда root.winfo_rootx() и root.winfo_rooty() получают положение пикселя в верхнем левом углу всего окна root.

Затем добавляются теги widget.winfo_x() и widget.winfo_y(), в основном просто получают координату пикселя верхнего левого пикселя виджета, который вы хотите захватить (в пикселях (x, y) вашего экрана).

Затем я нахожу (x1, y1), который является нижним левым пикселем виджета. ImageGrab.grab() создает печатный экран, а затем обрезаю его, чтобы получить только бит, содержащий виджет. Несмотря на то, что он не идеален и не создает наилучшего изображения, это отличный инструмент для простого получения изображения любого виджета и его сохранения.

Если у вас есть какие-либо вопросы, напишите комментарий! Надеюсь, это помогло!

Ответ 3

Может быть, вы можете попробовать использовать widget_winfo_id, чтобы получить HWND холста.

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

Ответ 4

Используйте Подушку для конвертации Postscript в 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')