0

I wish to take screenshot of python tkinter window (NOT the entire computer scrren). I applied following codes:

import pyautogui
import tkinter as tk

root= tk.Tk()

# Define tkinter window 
canvas1 = tk.Canvas(root, width = 300, height = 300)
canvas1.pack()

# Define fuction to take screenshot
def takeScreenshot ():
    
    myScreenshot = pyautogui.screenshot()
    myScreenshot.save('screenshot.png')


# Define fuction to take screenshot
myButton = tk.Button(text='Take Screenshot', command=takeScreenshot, bg='green',fg='white',font= 10)
canvas1.create_window(150, 150, window=myButton)

root.mainloop()

I wish to grab screenshot of only the window defined by "tk.Canvas(root, width = 300, height = 300)" But, I am capturing the entire screren.

Can somebody please let me know how do we go about this in python ?

Ranjan Pal
  • 307
  • 3
  • 13

3 Answers3

1

Since you are on windows you should be able to employ the win32 API,

Contrary to this you could use more simple solutions such as PyScreenshot

Take the following code for example:


from pyscreenshot import grab

im = grab(bbox=(100, 200, 300, 400))
im.show()

“ As you can see you can use bbox to take screenshot that is at co-ordinates (100, 200) and has a width of 300 and a height of 400.

This would require you knowing the position of the windows before hand- which you can do in Tkinter I believe.”

I found this information from previous SO questions. Here is another snippet that may help you.

Here's how you can do it using PIL on win32. Given a window handle (hwnd), you should only need the last 4 lines of code. The preceding simply search for a window with "firefox" in the title. Since PIL's source is available, you should be able to poke around the ImageGrab.grab(bbox) method and figure out the win32 code you need to make this happen.


from PIL import ImageGrab
import win32gui

toplist, winlist = [], []
def enum_cb(hwnd, results):
    winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
win32gui.EnumWindows(enum_cb, toplist)

firefox = [(hwnd, title) for hwnd, title in winlist if 'firefox' in title.lower()]
# just grab the hwnd for first window matching firefox
firefox = firefox[0]
hwnd = firefox[0]

win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()

Suggestions I found include: How to do a screenshot of a tkinter application?

How to Get a Window or Fullscreen Screenshot in Python 3k? (without PIL)

I hope this helps, sometimes all it takes is a good google search. If this help you please select this as the correct answer

Edit

Depending upon the contents of the window you could use this- if it is a drawing.

“ You can either generate a postscript document (to feed into some other tool: ImageMagick, Ghostscript, etc)”


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

Look at this if you are trying to save a drawing https://www.daniweb.com/programming/software-development/code/216929/saving-a-tkinter-canvas-drawing-python

Aiyush
  • 170
  • 13
1

You would need to define the rectangle for the screenshot

instead of myScreenshot = pyautogui.screenshot()

use the following in place of it:

myScreenshot = pyautogui.screenshot(region=(0,0, 300, 400))

The 4 points describe where you want the screenshot

https://pyautogui.readthedocs.io/en/latest/screenshot.html

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46
Rob Py
  • 156
  • 1
  • 1
  • 9
  • Thanks a lot @CoolCloud for your feedback..However, the "region" gives a scrrenshot of only part of a window and not the tkinter canvas window – Ranjan Pal Jan 07 '21 at 04:37
1

You can get the region of the canvas and pass them to screenshot():

def takeScreenshot():
    # get the region of the canvas
    x, y = canvas1.winfo_rootx(), canvas1.winfo_rooty()
    w, h = canvas1.winfo_width(), canvas1.winfo_height()
    pyautogui.screenshot('screenshot.png', region=(x, y, w, h))
acw1668
  • 40,144
  • 5
  • 22
  • 34