There are multiple ways to do that. The code for these will require modification based on your needs, so I will put in some pointers to the high level methods and libraries:
You can directly use GUI-automation tools such as
pyautoguito press Alt+PrntScreen and transfer the data from clipboard into a variable (http://pyautogui.readthedocs.io/en/latest/keyboard.html#keyboard-keys)You can use pywin32 and PIL to grab the image of a certain window (How to Get a Window or Fullscreen Screenshot (without PIL)?)
You can use ImageMagick to grab screenshots of a single window (https://www.imagemagick.org/discourse-server/viewtopic.php?t=24702)
You can use
pyautogui.locateOnScreen("Sceenshot.PNG")to find the tuple which will contain the boundaries of the window for your java app. Then you can pass it to your functionimg.ImageGrab.grab(bbox)
There are multiple ways to do that. The code for these will require modification based on your needs, so I will put in some pointers to the high level methods and libraries:
You can directly use GUI-automation tools such as
pyautoguito press Alt+PrntScreen and transfer the data from clipboard into a variable (http://pyautogui.readthedocs.io/en/latest/keyboard.html#keyboard-keys)You can use pywin32 and PIL to grab the image of a certain window (How to Get a Window or Fullscreen Screenshot (without PIL)?)
You can use ImageMagick to grab screenshots of a single window (https://www.imagemagick.org/discourse-server/viewtopic.php?t=24702)
You can use
pyautogui.locateOnScreen("Sceenshot.PNG")to find the tuple which will contain the boundaries of the window for your java app. Then you can pass it to your functionimg.ImageGrab.grab(bbox)
A example to get the content(screenshot) of a specific window with the help of the pygetwindow module.
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()
First time posting here, i am very new to python, but i want to make a screenshot of a specific window, instead of all of the screen, this is my current code that makes a screenshot of all of the screen
from PIL import ImageGrab
screen = ImageGrab.grab(bbox=(0,0,1366,768))
screen.save('grabbed.png')
print("done")I searched on internet but the only solution that i found was to get the size and position of the selected window and then take a screenshot with those info so it only gets that window, howewer if there is something covering that window it wont take the screenshot correctly... is it atleast possible?
How to take a screenshot/screen capture of a specific window?
MacOS: Using python to capture screenshots of a specific ...
Get screenshot on Windows with Python? - Stack Overflow
How i can screenshot a specific window?
Videos
import cv2 as cv
import numpy as np
from time import time
from mss import mss
from Quartz import CGWindowListCopyWindowInfo, kCGNullWindowID, kCGWindowListOptionAll
import Quartz
windowName = "Window Name like the name written on top of the window"
def get_window_dimensions(hwnd):
window_info_list = Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionIncludingWindow, hwnd)
for window_info in window_info_list:
window_id = window_info[Quartz.kCGWindowNumber]
if window_id == hwnd:
bounds = window_info[Quartz.kCGWindowBounds]
width = bounds['Width']
height = bounds['Height']
left = bounds['X']
top = bounds['Y']
return {"top": top, "left": left, "width": width, "height": height}
return None
def window_capture():
loop_time = time()
windowList = CGWindowListCopyWindowInfo(
kCGWindowListOptionAll, kCGNullWindowID)
for window in windowList:
print(window.get('kCGWindowName', ''))
if windowName.lower() in window.get('kCGWindowName', '').lower():
hwnd = window['kCGWindowNumber']
print('found window id %s' % hwnd)
monitor = get_window_dimensions(hwnd)
with mss() as sct:
# monitor = {"top": 40, "left": 0, "width": 800, "height": 600}
while (True):
screenshot = np.array(sct.grab(monitor))
screenshot = cv.cvtColor(screenshot, cv.COLOR_RGB2BGR)
cv.imshow('Computer Vision', screenshot)
print('FPS {}'.format(1 / (time() - loop_time)))
loop_time = time()
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
window_capture()
print('Done.')
A solution for the problem for macos, its easy to find the answer for windows but not so for mac. So here's the code folks. Solid 40fps... If you do the same by cv2 or pyautogui, it gives 5fps.
I wrote the following piece of ObjectiveC that gets the names, owners, window id and position on screen of all the windows in macOS. I saved it as windowlist.m and compiled it with the commands in the comments at the top of the file:
////////////////////////////////////////////////////////////////////////////////
// windowlist.m
// Mark Setchell
//
// Get list of windows with their characteristics
//
// Compile with:
// clang windowlist.m -o windowlist -framework coregraphics -framework cocoa
//
// Run with:
// ./windowlist
//
////////////////////////////////////////////////////////////////////////////////
#include <Cocoa/Cocoa.h>
#include <CoreGraphics/CGWindow.h>
int main(int argc, char **argv)
{
NSArray *windows = (NSArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly,kCGNullWindowID);
for(NSDictionary *window in windows){
int WindowNum = [[window objectForKey:(NSString *)kCGWindowNumber] intValue];
NSString* OwnerName = [window objectForKey:(NSString *)kCGWindowOwnerName];
int OwnerPID = [[window objectForKey:(NSString *) kCGWindowOwnerPID] intValue];
NSString* WindowName= [window objectForKey:(NSString *)kCGWindowName];
CFDictionaryRef bounds = (CFDictionaryRef)[window objectForKey:(NSString *)kCGWindowBounds];
CGRect rect;
CGRectMakeWithDictionaryRepresentation(bounds,&rect);
printf("%s:%s:%d:%d:%f,%f,%f,%f\n",[OwnerName UTF8String],[WindowName UTF8String],WindowNum,OwnerPID,rect.origin.x,rect.origin.y,rect.size.height,rect.size.width);
}
}
It gives output like this, where the last 4 items on each line are the window top-left corner, height and width. You can either run this program "as is" with Python's subprocess.Popen() and get the window list, or you could maybe convert it to Python using PyObjc Python module:
Location Menu:Item-0:4881:1886:1043.000000,0.000000,22.000000,28.000000
Backup and sync from Google:Item-0:1214:8771:1071.000000,0.000000,22.000000,30.000000
Dropbox:Item-0:451:1924:1101.000000,0.000000,22.000000,28.000000
NordVPN IKE:Item-0:447:1966:1129.000000,0.000000,22.000000,26.000000
PromiseUtilityDaemon:Item-0:395:1918:1155.000000,0.000000,22.000000,24.000000
SystemUIServer:AppleTimeMachineExtra:415:1836:1179.000000,0.000000,22.000000,40.000000
SystemUIServer:AppleBluetoothExtra:423:1836:1219.000000,0.000000,22.000000,30.000000
SystemUIServer:AirPortExtra:409:1836:1249.000000,0.000000,22.000000,30.000000
SystemUIServer:AppleVolumeExtra:427:1836:1279.000000,0.000000,22.000000,30.000000
SystemUIServer:BatteryExtra:405:1836:1309.000000,0.000000,22.000000,67.000000
SystemUIServer:AppleClockExtra:401:1836:1376.000000,0.000000,22.000000,123.000000
SystemUIServer:AppleUser:419:1836:1499.000000,0.000000,22.000000,99.000000
Spotlight:Item-0:432:1922:1598.000000,0.000000,22.000000,36.000000
SystemUIServer:NotificationCenter:391:1836:1634.000000,0.000000,22.000000,46.000000
Window Server:Menubar:353:253:0.000000,0.000000,22.000000,1680.000000
Dock:Dock:387:1835:0.000000,0.000000,1050.000000,1680.000000
Terminal:windowlist โ -bash โ 140ร30:4105:6214:70.000000,285.000000,658.000000,1565.000000
Another approach that is really fast is the MSS module. It is different from other solutions in the way that it uses only the ctypes standard module, so it does not require big dependencies. It is OS independant and its use is made easy:
from mss import mss
with mss() as sct:
sct.shot()
And just find the screenshot.png file containing the screen shot of the first monitor. There are a lot of possibile customizations, you can play with ScreenShot objects and OpenCV/Numpy/PIL/etc..
Worth noting that ImageGrab only works on MSWindows.
For cross platform compatibility, a person may be best off with using the wxPython library. http://wiki.wxpython.org/WorkingWithImages#A_Flexible_Screen_Capture_App
import wx
app = wx.App() # Need to create an App instance before doing anything
screen = wx.ScreenDC()
size = screen.GetSize()
bmp = wx.Bitmap(size[0], size[1])
mem = wx.MemoryDC(bmp)
mem.Blit(0, 0, size[0], size[1], screen, 0, 0)
del mem # Release bitmap
bmp.SaveFile('screenshot.png', wx.BITMAP_TYPE_PNG)