1

I am creating a small program to take screenshots. It works fine when capturing the entire screen but not when capturing a specific window, as it expands a bit more than it should

import keyboard, win32gui
from tkinter import filedialog
import pyautogui as pg

# Open file explorer for save file in a location
def save_file():
    global file
    filetypes = [("PNG files", ".png"), ("JPG files", ".jpg"), ("All files", "*")]
    file = filedialog.asksaveasfilename(defaultextension=".png",
                                        filetypes=filetypes,
                                        initialdir="C:/Users/Prado/Imágenes/Screenshoots",
                                        initialfile="my_screenshoot")    

# Take a screenshot of the entire screen
def full_screenshot():
    save_file()
    pg.screenshot(file)

# Take a screenshot of a specific window
def window_screenshot():
    save_file()
    w = win32gui
    window_region = w.GetWindowRect(w.FindWindow(None, w.GetWindowText(w.GetForegroundWindow())))  # Get position and size of the current window
    pg.screenshot(file, region=window_region)
    print(window_region)


keyboard.add_hotkey("alt + insert", window_screenshot)
keyboard.add_hotkey("ctrl + insert", full_screenshot)
keyboard.wait("esc")

I already tried taking captures from different windows and the additional pixels always vary

Test 1 Test 2 Test 3

Prado910
  • 21
  • 5

1 Answers1

0

The output of win32gui.GetWindowRect and the input of pyautogui.screenshot differ:

  • The win32gui tuple consists of (left, top, right, bottom)
  • The pyautogui tuple consists of (left, top, width, height)

Hence, you must not directly use the window_region as an argument, but convert it first:

#[...]
def window_screenshot():
    save_file()
    w = win32gui
    window_region = w.GetWindowRect(w.FindWindow(None, w.GetWindowText(w.GetForegroundWindow())))  # Get position and size of the current window
    left, top, right, bottom = window_region
    screenshot_region = (left, top, right - left, bottom - top)
    pg.screenshot(file, region=screenshot_region)
#[...]

P.S.: this will still contain the drop shadow of the window, so it might look "a little bit too large". To get the coordinates of the window without that shadow, you could use the DwmGetWindowAttribute, see https://stackoverflow.com/a/54770938/9501624 for an example.

Christian Karcher
  • 2,533
  • 1
  • 12
  • 17
  • Thanks, this solved my problem, plus I had to do this because the program was taking a few more pixels screenshot_region = (left + 8, top + 8, right - left - 16, bottom - top - 16) – Prado910 Dec 05 '22 at 20:39