Reputation: 606
I am using pyautogui in python for the screenshots
import pyautogui
screen = pyautogui.screenshot()
screen.save("file.jpg")
It works fine on a single screen on all platforms. But in a multiscreen system, it combines the two screens in a single screenshot. but I want a screenshot of a monitor which one is currently on use.
Upvotes: 4
Views: 21651
Reputation: 194
mss
package can easily solve this problempip install mss
🌟 First Monitor 🌟
import os
import os.path
import mss
def on_exists(fname):
# type: (str) -> None
"""
Callback example when we try to overwrite an existing screenshot.
"""
if os.path.isfile(fname):
newfile = fname + ".old"
print("{} -> {}".format(fname, newfile))
os.rename(fname, newfile)
with mss.mss() as sct:
filename = sct.shot(output="mon-{mon}.png", callback=on_exists)
print(filename)
🌟 Second Monitor 🌟
import mss
import mss.tools
with mss.mss() as sct:
# Get information of monitor 2
monitor_number = 2
mon = sct.monitors[monitor_number]
# The screen part to capture
monitor = {
"top": mon["top"],
"left": mon["left"],
"width": mon["width"],
"height": mon["height"],
"mon": monitor_number,
}
output = "sct-mon{mon}_{top}x{left}_{width}x{height}.png".format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
mss.tools.to_png(sct_img.rgb, sct_img.size, output=output)
print(output)
🌟 Use with OpenCV 🌟
import mss
import cv2
import numpy as np
with mss.mss() as sct:
# Get information of monitor 2
monitor_number = 2
mon = sct.monitors[monitor_number]
# The screen part to capture
monitor = {
"top": mon["top"],
"left": mon["left"],
"width": mon["width"],
"height": mon["height"],
"mon": monitor_number,
}
output = "sct-mon{mon}_{top}x{left}_{width}x{height}.png".format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
img = np.array(sct.grab(monitor)) # BGR Image
# Display the picture
cv2.imshow("OpenCV", img)
cv2.waitKey(0)
sct.monitors
will contain more than one item even if you have a single monitor because the first item will be the combined screens>>> sct.monitors # if we have a single monitor
[{'left': 0, 'top': 0, 'width': 1366, 'height': 768},
{'left': 0, 'top': 0, 'width': 1366, 'height': 768}]
>>> sct.monitors # if we have two monitors
[{'left': 0, 'top': 0, 'width': 3286, 'height': 1080},
{'left': 1920, 'top': 0, 'width': 1366, 'height': 768},
{'left': 0, 'top': 0, 'width': 1920, 'height': 1080}]
Upvotes: 9
Reputation: 71
found an solution here!
from PIL import ImageGrab
from functools import partial
ImageGrab.grab = partial(ImageGrab.grab, all_screens=True)
pyautogui.screenshot() will capture all screens.
Upvotes: 7
Reputation:
If you visit the official documentation website of you will see this :
Q: Does PyAutoGUI work on multi-monitor setups.
A: No, right now PyAutoGUI only handles the primary monitor.
You can use the mss module for this purpose.
from mss import mss
#One screenshot per monitor:
for filename in screenshotter.save():
print(filename)
#Screenshot of the monitor 1:
for filename in screenshotter.save(screen=1):
print(filename)
#Screenshot of the monitor 1, with callback:
def on_exists(fname):
''' Callback example when we try to overwrite an existing
screenshot.
'''
from os import rename
from os.path import isfile
if isfile(fname):
newfile = fname + '.old'
print('{0} -> {1}'.format(fname, newfile))
rename(fname, newfile)
return True
for filename in screenshotter.save(screen=1, callback=on_exists):
print(filename)
#A screenshot to grab them all:
for filename in screenshotter.save(output='fullscreen-shot.png', screen=-1):
print(filename)
Upvotes: 5