簡體   English   中英

如何將 canvas 內容轉換為圖像?

[英]How can I convert canvas content to an image?

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

我想將 canvas 內容轉換為 bitmap 或其他圖像,然后進行其他操作,例如旋轉或縮放圖像,或更改其坐標。

如果我不再繪圖,位圖可以提高顯示效率。

我應該怎么辦?

我找到了一個很好的方法來做到這一點,這真的很有幫助。 為此,您需要 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()制作一個打印屏幕,然后我裁剪它以只獲取包含小部件的位。 雖然不完美,也不會制作出最好的圖像,但這是一個很好的工具,用於獲取任何小部件的圖像並保存它。

如果您有任何問題,請發表評論! 希望這有幫助!

您可以生成一個 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()

使用 Pillow 將 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') 

也許您可以嘗試使用 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

@B.Jenkins 的答案的更好方法不需要引用根 object:

from PIL import ImageGrab


def save_widget_as_image(widget, file_name):
    ImageGrab.grab(bbox=(
        widget.winfo_rootx(),
        widget.winfo_rooty(),
        widget.winfo_rootx() + widget.winfo_width(),
        widget.winfo_rooty() + widget.winfo_height()
    )).save(file_name)

在我的系統上,ghostscript 和 ImageGrab 通常存在嚴重問題。 解決方案在PIL Image上繪制,另存為文件,在PhotoImage上加載文件,用於新建TKinter Canvas。

canvas = Canvas(win, width=IMG_W, height=IMG_H)
img = PILImg.new("RGB", (IMG_W, IMG_H), "#000")
draw = ImageDraw.Draw(img)
draw.rectangle([x,y,w,h], fill=color, outline=border)
img.save("stock-chart.png")
copyImg = PhotoImage(file="stock-chart.png")
canvas.create_image(IMG_W_2, IMG_H_2, image=copyImg)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM