Saving screen-shot of tkinter window as image

  • Thread starter Thread starter Eclair_de_XII
  • Start date Start date
  • Tags Tags
    Image Window
Click For Summary
The discussion revolves around a Python script that captures screenshots of a specific window using the PIL library and the win32gui module. The initial implementation faced issues with the saved image being off-center both horizontally and vertically. To address this, the user switched to using the pyscreenshot library and adjusted the capture dimensions manually, which, while not efficient, resolved the problem.The code includes functions to find a suitable filename for the screenshot, save the image, and handle the window geometry for accurate capturing. The user noted that the screenshot might include more than just the intended window, suggesting that the bounding box used for capturing could be too large. Documentation for PIL.ImageGrab was referenced, indicating that the bounding box can be omitted to capture the entire screen, which may lead to unintended content in the screenshot. Overall, the discussion highlights troubleshooting steps and adjustments made to improve the accuracy of window captures in Python.
Eclair_de_XII
Messages
1,082
Reaction score
91
TL;DR
Using PIL and win32gui in order to capture tkinter window as image, then save to file. It's always off-center, and I haven't a clue why.
[CODE lang="python" highlight="26,27,28,33"]from PIL import ImageGrab
from win32gui import GetWindowRect

def find_img_loc():
k=1
folder=sep.join((getcwd(),'screenshots'))
initial_file='screenshot'+str(k)
filename=lambda x: sep.join((folder,x+'.png'))
while exists(filename(initial_file)):
k+=1
n=len(str(k-1))
initial_file=initial_file[:-n]+str(k)
kw={
'initialfile':initial_file,\
'defaultextension':'png',\
'initialdir':folder,\
'filetypes':[('.png files only','*.png')]
}
filename=filedialog.asksaveasfilename(**kw)
return filename

def save_image(root):
if not exists('screenshots'):
mkdir('screenshots')
root.update()
HWND = root.winfo_id() # get the handle of the canvas
rect = GetWindowRect(HWND) # get the coordinate of the canvas
I am = ImageGrab.grab(rect) # get image of the current location
filename=find_img_loc()
if not filename:
return
else:
im.save(filename,format='png')

if __name__ == '__main__':
root=Tk()
lines='Sample text here','More sample text...','One more for the road.'
for n, text in enumerate(lines):
Label(root,text=text).grid(row=n)
save_image(root)
root.destroy()[/CODE]

This code was actually from:

https://stackoverflow.com/questions/9886274/how-can-i-convert-canvas-content-to-an-image
 
Last edited:
Technology news on Phys.org
how is it off center? horizontally or vertically or both?
 
It was both.

The actual window looks like this:

actual.png
but the saved image looks like this:
screenshot4.png
In any case, I resolved the issue (partially) by using pyscreenshot.grab and manually tinkering with the capture dimensions. It was not efficient, I confess, but it did the trick alright

Python:
from os import mkdir, getcwd
from os.path import exists, sep

from pyscreenshot import grab

def find_img_loc():
    k=1
    folder=sep.join((getcwd(),'screenshots'))
    initial_file='screenshot'+str(k)
    filename=lambda x: sep.join((folder,x+'.png'))
    while exists(filename(initial_file)):
        k+=1
        n=len(str(k-1))
        initial_file=initial_file[:-n]+str(k)
    kw={
        'initialfile':initial_file,\
        'defaultextension':'png',\
        'initialdir':folder,\
        'filetypes':[('.png files only','*.png')]
        }
    filename=filedialog.asksaveasfilename(**kw)
    return filename

def save_image(im):
    if not exists('screenshots'):
        mkdir('screenshots')
    filename=find_img_loc()
    if not filename:
        return
    else:
        im.save(filename,format='png')

def save_image2(root):
    root.update()
    geometry=root.winfo_geometry()
    position=geometry.split('+')
    dimension=position[0].split('x')
    xlen=dimension[0]
    ylen=dimension[1]
    xpos=position[1]
    ypos=position[2]
    geo_list=(xpos,ypos,xlen,ylen)
    geometry=()
    k=1.25
    for n,g in enumerate(geo_list):
        g=int(g)
        g=k*g
        if n == 0:
            g+=10
        g=int(g)
        if n>1:
            h=geo_list[n-2]
            h=int(h)
            h=k*h
            k*=1.075
            h=int(h)
            geometry+=(g+h,)
        else:
            geometry+=(g,)
    im=grab(bbox=geometry)
    save_image(im)

if __name__ == '__main__':
    root=Tk()
    root.geometry('400x400+400+100')
    Label(root,text='Yabba dabba doo').grid()
    save_image1(root)
 
Could it be that the screenshot you captured included more than just that one text window? If you manually capture a screenshot of that window, and then paste it into, say, Paint or other graphics app, do you get just that single window or do you get more?

Some documentation I found here says this. Note the last sentence.
PIL.ImageGrab.grab(bbox=None, include_layered_windows=False, all_screens=False, xdisplay=None)
Take a snapshot of the screen. The pixels inside the bounding box are returned as an “RGBA” on macOS, or an “RGB” image otherwise. If the bounding box is omitted, the entire screen is copied.
 
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...