Performing ImageGrab on tkinter Screen

3k Views Asked by At

I am trying to save a tkinter screen to a file (to later convert into a video).

I can't get the correct position of the canvas for using ImageGrab.

My relevant imports are:

import tkinter
import pyscreenshot as ImageGrab 

I am trying to save the screen using (after drawing the screen):

grab = ImageGrab.grab(bbox=canvas.bbox())
ImageGrab.grab_to_file(fileName,grab)

I don't know how to get the canvas position for using "ImageGrab.grab".

Is there any way to get the bounding box for the whole canvas, so as to later use ImageGrab to store a screenshot?

---Edit------------------------------------------------------------------

Solution:

box = (canvas.winfo_rootx(),canvas.winfo_rooty(),canvas.winfo_rootx()+canvas.winfo_width(),canvas.winfo_rooty() + canvas.winfo_height())
grab = ImageGrab.grab(bbox = box)
grab.save(file_path)
1

There are 1 best solutions below

0
furas On BEST ANSWER

You have methods like winfo_x(), winfo_y() to get position inside parent widget (it doesn't have to be main window), and winfo_rootx(), winfo_rooty() to get position on screen.

Effbot.org: Basic Widget Methods

Code displays canvas' position on screen and inside parent Frame

import tkinter as tk

def callback():
    print('  root.geometry:', root.winfo_geometry())
    print('canvas.geometry:', canvas.winfo_geometry())
    print('canvas.width :', canvas.winfo_width())
    print('canvas.height:', canvas.winfo_height())
    print('canvas.x:', canvas.winfo_x())
    print('canvas.y:', canvas.winfo_y())
    print('canvas.rootx:', canvas.winfo_rootx())
    print('canvas.rooty:', canvas.winfo_rooty())

root = tk.Tk()

tk.Label(root, text='SOME WIDGETS IN ROOT').pack()

frame = tk.Frame(root)
frame.pack()

tk.Label(frame, text='SOME WIDGETS IN FRAME').pack()

canvas = tk.Canvas(frame, bg='green')
canvas.pack()

print('\n--- before mainloop start---\n')
callback()

print('\n--- after mainloop start ---\n')
root.after(100, callback)

root.mainloop()

Example result

--- before mainloop start ---

  root.geometry: 1x1+0+0
canvas.geometry: 1x1+0+0
canvas.width : 1
canvas.height: 1
canvas.x: 0
canvas.y: 0
canvas.rootx: 0
canvas.rooty: 0

--- after mainloop start ---

  root.geometry: 380x303+770+462
canvas.geometry: 380x267+0+18
canvas.width : 380
canvas.height: 267
canvas.x: 0
canvas.y: 18
canvas.rootx: 770
canvas.rooty: 498