How to Get a Window or Fullscreen Screenshot (without PIL)?
Solution 1
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()
Solution 2
Ars gave me all the pieces. I am just putting the pieces together here for anyone else who needs to get a screenshot in python 3.x. Next I need to figure out how to work with a win32 bitmap without having PIL to lean on.
Get a Screenshot (pass hwnd for a window instead of full screen):
def screenshot(hwnd = None):
import win32gui
import win32ui
import win32con
from time import sleep
if not hwnd:
hwnd=win32gui.GetDesktopWindow()
l,t,r,b=win32gui.GetWindowRect(hwnd)
h=b-t
w=r-l
hDC = win32gui.GetWindowDC(hwnd)
myDC=win32ui.CreateDCFromHandle(hDC)
newDC=myDC.CreateCompatibleDC()
myBitMap = win32ui.CreateBitmap()
myBitMap.CreateCompatibleBitmap(myDC, w, h)
newDC.SelectObject(myBitMap)
win32gui.SetForegroundWindow(hwnd)
sleep(.2) #lame way to allow screen to draw before taking shot
newDC.BitBlt((0,0),(w, h) , myDC, (0,0), win32con.SRCCOPY)
myBitMap.Paint(newDC)
myBitMap.SaveBitmapFile(newDC,'c:\\tmp.bmp')
Get a Window Handle by title (to pass to the above function):
def _get_windows_bytitle(title_text, exact = False):
def _window_callback(hwnd, all_windows):
all_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
windows = []
win32gui.EnumWindows(_window_callback, windows)
if exact:
return [hwnd for hwnd, title in windows if title_text == title]
else:
return [hwnd for hwnd, title in windows if title_text in title]
Solution 3
This will take a new opened window and make a screenshot of it and then crop it with PIL also possible to find your specific window with pygetwindow.getAllTitles() and then fill in your window name in z3 to get screenshot of only that window.
If you definitely not want to use PIL you can maximize window with pygetwindow module and then make a screenshot with pyautogui module.
Note: not tested on Windows XP (but tested on Windows 10)
import pygetwindow
import time
import os
import pyautogui
import PIL
# get screensize
x,y = pyautogui.size()
print(f"width={x}\theight={y}")
x2,y2 = pyautogui.size()
x2,y2=int(str(x2)),int(str(y2))
print(x2//2)
print(y2//2)
# find new window title
z1 = pygetwindow.getAllTitles()
time.sleep(1)
print(len(z1))
# test with pictures folder
os.startfile("C:\\Users\\yourname\\Pictures")
time.sleep(1)
z2 = pygetwindow.getAllTitles()
print(len(z2))
time.sleep(1)
z3 = [x for x in z2 if x not in z1]
z3 = ''.join(z3)
time.sleep(3)
# also able to edit z3 to specified window-title string like: "Sublime Text (UNREGISTERED)"
my = pygetwindow.getWindowsWithTitle(z3)[0]
# quarter of screen screensize
x3 = x2 // 2
y3 = y2 // 2
my.resizeTo(x3,y3)
# top-left
my.moveTo(0, 0)
time.sleep(3)
my.activate()
time.sleep(1)
# save screenshot
p = pyautogui.screenshot()
p.save(r'C:\\Users\\yourname\\Pictures\\\\p.png')
# edit screenshot
im = PIL.Image.open('C:\\Users\\yourname\\Pictures\\p.png')
im_crop = im.crop((0, 0, x3, y3))
im_crop.save('C:\\Users\\yourname\\Pictures\\p.jpg', quality=100)
# close window
time.sleep(1)
my.close()
KobeJohn
Updated on January 25, 2022Comments
-
KobeJohn over 2 years
With python 3, I'd like to get a handle to another window (not part of my application) such that I can either:
- directly capture that window as a screenshot, or
- determine its position and size and capture it some other way
In case it is important, I am using Windows XP (edit: works in Windows 7 also).
I found this solution, but it is not quite what I need since it is full screen and more importantly, PIL to the best of my knowledge does not support 3.x yet.