如何在不保存的情况下在python窗口中显示图像/屏幕截图

时间:2019-05-07 12:25:40

标签: python image tkinter

我想在新的tkinter窗口(TopLevel)中显示我的屏幕截图,但是我不想将其保存在PC上。当我保存它时,它可以正常工作,但是当我尝试从内存中加载屏幕截图时,我遇到了错误:图像不存在。

我的主窗口是root = Tk()

我通过按钮调用此功能:

def screenshot():
    x = 500
    y = 500
    im1 = pyautogui.screenshot(region=(x, y, 100, 100))
    im1.save('test.png')

    New = Toplevel(root)
    im1 = ImageTk.PhotoImage(Image.open("test.png"))
    image1 = Label(New, image = im1)
    image1.image = im1
    image1.place(x=0, y=0)

这很好,但是当我尝试这样做时:

def screenshot():
    x = 500
    y = 500
    im1 = pyautogui.screenshot(region=(x, y, 100, 100))

    New = Toplevel(root)
    image1 = Label(New, image = im1)
    image1.image = im1
    image1.place(x=0, y=0)

我遇到错误:

_tkinter.TclError: image "<PIL.Image.Image image mode=RGB size=100x100 at 0xB4367F0>" doesn't exist

如何显示我的屏幕快照而不保存它?

编辑: 我使用os.remove代码绕过了自己的问题,如下所示:

def screenshot():
    x = 500
    y = 500
    im1 = pyautogui.screenshot(region=(x, y, 100, 100))
    im1.save('test.png')

    New = Toplevel(root)
    im1 = ImageTk.PhotoImage(Image.open('test.png'))
    image1 = Label(New, image = im1)
    image1.image = im1
    image1.place(x=0, y=0)
    os.remove('test.png')

这工作得很好,但是我仍然对是否可以以某种方式不用im1.save做到这一点感兴趣。 我对编程还很陌生,所以如果我的解决方案还可以,请给我提示。

2 个答案:

答案 0 :(得分:1)

解决您的问题非常简单。从错误消息"_tkinter.TclError: image "<PIL.Image.Image image mode=RGB size=100x100 at 0xB4367F0>" doesn't exist"中,我看到图像为PIL格式。基本上,您只需要从PIL库导入ImageTk并在捕获屏幕后在函数中执行im1 = ImageTk.PhotoImage(im1)

这是您的职能。

def screenshot():
    x = 500
    y = 500
    # Can use ImageGrab to capture the screen as well
    im1 = pyautogui.screenshot(region=(x, y, 100, 100))

    New = Toplevel(root)
    im1 = ImageTk.PhotoImage(im1)      # converting PIL to support Tkinter format
    image1 = Label(New, image = im1)
    image1.image = im1
    image1.place(x=0, y=0)

如果您只是使用 pyautogui 来捕获屏幕,那么我建议使用这种方式from PIL import ImageGrab, ImageTk,您甚至不需要 pyautogui 并将其替换为ImageGrab.grab(bbox))

示例:

from tkinter import *
import pyautogui
from PIL import ImageTk, ImageGrab

root = Tk()

def screenshot():
    x = 500
    y = 500

    # ----They both show the same results-----

    # im1 = pyautogui.screenshot(region=(x, y, 100, 100))   
    im1 = ImageGrab.grab((x, y, x+100, y+100)) # bbox =  (x1, y1, x2, y2)  

    New = Toplevel(root)
    im1 = ImageTk.PhotoImage(im1)
    image1 = Label(New, image = im1)
    image1.image = im1
    image1.place(x=0, y=0)

Button(root, text='ScreenShot', padx=10, command=screenshot).pack(padx=10, pady=10)

mainloop()

答案 1 :(得分:0)

尝试一下:

from tkinter import *

# pip install pillow

from PIL import Image, ImageTk
from pyautogui import screenshotUtil

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.pack(fill=BOTH, expand=1)

        im=screenshotUtil.screenshot()

        #load = Image.open("my_screenshot.png")
        render = ImageTk.PhotoImage(im)
        img = Label(self, image=render)
        img.image = render
        img.place(x=0, y=0)


root = Tk()
app = Window(root)
root.wm_title("Tkinter window")
root.geometry("200x120")
root.mainloop()