如何将画布内容转换为图像?

liu*_*xin 19 python tkinter bitmap

from Tkinter import *
root = Tk()
cv = Canvas(root)
cv.create_rectangle(10,10,50,50)
cv.pack()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

我想将画布内容转换为位图或其他图像,然后执行其他操作,例如旋转或缩放图像,或更改其坐标.

位图可以提高效率,以显示我是否不再绘图.

我该怎么办?

小智 22

您可以生成一个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()
Run Code Online (Sandbox Code Playgroud)

或者在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()
Run Code Online (Sandbox Code Playgroud)


B.J*_*ins 20

我找到了一个很好的方法,这真的很有帮助.为此,您需要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")
Run Code Online (Sandbox Code Playgroud)

这样做是将小部件名称传递给函数.该命令root.winfo_rootx()root.winfo_rooty()获取整个root窗口左上角的像素位置.

然后,widget.winfo_x()widget.winfo_y()被添加到,基本上只是让你想要捕捉(在像素(X,你的屏幕Y))widget的左上角像素的像素坐标.

然后我找到(x1,y1)这是小部件的左下角像素.将ImageGrab.grab()使得PRINTSCREEN,然后我裁剪只得到包含插件的位.虽然不完美,并且不会产生最佳图像,但这是一个很好的工具,只需获取任何小部件的图像并保存它.

如果您有任何疑问,请发表评论!希望这有帮助!

  • @EerikMuuli首先,你使用pyscreenshot模块而不是PIL,所以我不完全确定它是如何工作的.由于PIL可以进行屏幕截图和许多其他功能,我只需要使用PIL模块.此外,看起来你只想制作画布,并制作一个矩形图片.有更简单的方法来做到这一点!为了你的方式,然后使用PIL,以及我在我的答案中使用的保存功能,如果你真的想在截取屏幕截图后退出,那么只需输入exit()或者最好是root.destroy()命令在getter函数定义中. (2认同)
  • 奇妙的方法!比尝试在空白 PIL 图像上重复所有绘图命令或创建 Postscipt 输出并使用其他工具将其转换为图像要好得多。请注意,这可以通过 `ImageGrab.grab((x,y,x1,y1)).save("file path here")` 一步完成,而不是捕获整个屏幕然后裁剪它(请参阅[ `ImageGrab.grab()`](http://pillow.readthedocs.io/en/4.1.x/reference/ImageGrab.html) 文档)。还应该指出,给出的文件扩展名决定了创建的图像文件的格式。 (2认同)
  • `ImportError: ImageGrab 仅适用于 macOS 和 Windows` (2认同)

小智 5

使用 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') 
Run Code Online (Sandbox Code Playgroud)

  • 当我尝试此操作时,我从 PIL (Pillow) 收到错误“OSError:无法在路径上找到 Ghostscript”。 (8认同)

小智 5

也许您可以尝试使用 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
Run Code Online (Sandbox Code Playgroud)

  • 您不需要使用“win32gui”来获取画布的坐标。为此有内置的“tkinter”方法。 (2认同)