asweigart / pyscreeze Goto Github PK
View Code? Open in Web Editor NEWPyScreeze is a simple, cross-platform screenshot module for Python 2 and 3.
License: BSD 3-Clause "New" or "Revised" License
PyScreeze is a simple, cross-platform screenshot module for Python 2 and 3.
License: BSD 3-Clause "New" or "Revised" License
File "/Users/nick/Documents/antiAfkflorrio/venv/lib/python3.9/site-packages/pyscreeze/init.py", line 527, in _screenshot_osx:
solution:
So you need to click into the reported error file. Replace this code:
if tuple(PIL__version__) < (6, 2, 1):
with this code:
if tuple(map(int, PIL__version__.split("."))) < (6, 2, 1):
works for me
Thanks for providing such an interesting tool!
If on Linux, when passing region
into the screenshot()
, it will be faster to utilize the -a
option for scrot
.
Basically, we can change this line https://github.com/asweigart/pyscreeze/blob/master/pyscreeze/__init__.py#L475
to something like:
if region is None:
subprocess.call(['scrot', '-z', tmpFilename])
else:
str_region = ','.join([str(x) for x in region])
subprocess.call(['scrot', '-a', str_region, '-z', tmpFilename])
I tested the difference between two versions use this code snippet:
for i in range(100):
screenshot = pyscreeze.screenshot(region=(0, 0, 300, 600))
The -a
version only took 3s while the default version took 33s. (I have two monitors :)
Thanks again!
Pip install fails with FileNotFoundError
FileNotFoundError: [Errno 2] No such file or directory: 'README.md'
The error comes up for version pyscreeze>=0.1.15.
Version pyscreeze<=0.1.14 works fine!
Workaround:
pip install pyscreeze==0.1.14
Full stacktrace:
$ pip install pyscreeze
Looking in indexes: https://pypi.org/simple
Collecting pyscreeze
Using cached https://files.pythonhosted.org/packages/c9/6e/e175fda37d76d7846a6cda8a4364dfd7c2d343139b0716c4f03194d14933/PyScreeze-0.1.17.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-z0taorod/pyscreeze/setup.py", line 10, in <module>
with open("README.md", "r") as fh:
FileNotFoundError: [Errno 2] No such file or directory: 'README.md'
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-z0taorod/pyscreeze/
A few people have contacted me about this error, so Im making an issue here. This error happens during image searching. The error only occurs when the program has been image searching for longer periods of time, and happens rather inconsistently.
User reports this bug:
Python3 on Ubuntu 16.04
I have a line in my script :
pyautogui.screenshot('quad1.png' , region=(15, 38, 501, 404))
When that runs it gives me a screen shot of the entire screen, not just the region described.
I'm taking a screenshot of region but instead I have full desktop screenshot
import pyscreeze
import cv2
import numpy as np
import os
import pathlib
os.chdir(pathlib.Path(__file__).parent.resolve())
screenshot = pyscreeze.screenshot(region=(0,0, 50,50))
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
cv2.imwrite('captured-screen.png', screenshot)
my hardware setup:
macmini m2, one monitor
Hi all,
_screenshot_osx function throws an error, because of the Pillow version check.
Basically a tuple with one string is compared to a tuple with ints.
I suggest adding these two lines to the top of the function:
if isinstance(PIL__version__, str):
PIL__version__ = (int(value) for value in PIL__version__.split('.'))
This creates a generator so when tuple(PIL__version__) is called it will create (x, y, z) instead of ("x.y.z") and the comparison can work as expected.
PR #83 on pyautogui asweigart/pyautogui#83 added support for maim to take screenshots on linux. These changes should be merged to pyscreeze, and the documentation should be updated.
In my testing with pyautogui in Python 3.9, currently this package crashes with a NameError: name 'Image' is not defined
due to an old Pillow dependency, that is resolved just updating the Pillow package version.
scrot does not provide the '-z' option on all Linux distributions. This causes a warning on distributions where this option is missing (e.g. Fedora, CentOS, RHEL):
>>> import pyscreeze
>>> img=pyscreeze.screenshot()
scrot: invalid option -- 'z'
If you use the screenshot function repeatedly in your script, the console will get flooded with this warning message.
Idea for a new feature: when calling the locate functions, any fully transparent pixels in the needle image should match any pixel on the screen.
For example, an all-red image is used as the needle image for a screenshot or another image. Even if a red patch is not in the haystack image, the locate functions return a match at (0, 0)
Hi!
Is it possible some how to mute scrot arguing about invalid option -z?
I tried to mute the option by providing '' in the pyscreeze, but it started to generate error about scaling or smth.
The problem is that my console is filled with these messages after any locate* call.
I use scrot 0.8 on linux x86_64
From a user: My screen resolution is 3200x1200 but when I bring my mouse to the bottom right corner of the screen I get 2133, 1199.
pixelMatchesColor
can never deal with RGBA because pixel
always returns a tuple of length 3
Error is:
line 234, in _locateAll_python
raise StopIteration()
StopIteration
there are no problems in Python 3.6 on 32bit. I confirmed on multiple programs that the image is there and that these work on the previous version.
This is a new error that just started happened when I upgraded to 3.7 on 64 bit.
One more error that is showing during the shell screen:
Python37\lib\site-packages\pyscreeze\__init__.py", line 250, in locate
points = tuple(locateAll(needleImage, haystackImage, **kwargs))
RuntimeError: generator raised StopIteration
These new features should be included in the docs and test coverage.
With the current code, if you try to do locateCenterOnScreen(), and you are using the default "return None" approach, you get the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python\Python37\lib\site-packages\pyscreeze\__init__.py", line 319, in locateCenterOnScreen
return center(coords)
File "C:\Python\Python37\lib\site-packages\pyscreeze\__init__.py", line 427, in center
return Point(coords[0] + int(coords[2] / 2), coords[1] + int(coords[3] / 2))
TypeError: 'NoneType' object is not subscriptable
This can be corrected by changing the center() function to read:
def center(coords):
if coords is None:
return coords
else:
return Point(coords[0] + int(coords[2] / 2), coords[1] + int(coords[3] / 2))
Is it an intended feature in V0.1.19 to raise ImageNotFoundException when there is no matches?
In v0.1.18 there was a RAISE_IF_NOT_FOUND set to false by default.
Edit: Apparently this was answered in issue #294 of pyautogui https://github.com/asweigart/pyautogui/issues/294
I close the issue.
As title, the screenshot functionality does not work on macOS Mojave, as detailed on this thread:
Hi , I am currently using pyautogui
Which using this backend for pixel getting.
windll.gdi32.GetPixel(0, 8, 8)
File "\pyscreeze\__init__.py", line 608, in pixel
color = windll.gdi32.GetPixel(hdc, x, y)
ctypes.ArgumentError: argument 1: <class 'OverflowError'>: int too long to convert
this would happend when i was trying to capture Top Most Seted Window Pixel
I searched Other Issue , But Non of them fits for me.
I've never had problem to run pixel function on Python 3.7, but after I updated to Python 3.8 the pixel function returns this:
OSError: windll.user32.ReleaseDC failed : return 0
I solved this using pixel with try/except
:
try:
a = pixel(100,100)
except:
a = pixel(100,100)
I have no clue why this works, but it's working.
I running the script in Windows 10, Python 3.8.5 and Pyscreeze 0.1.26.
import cv2
full_img = cv2.imread('img.png')
board = cv2.imread('img.png')
import pyscreeze
coords = pyscreeze.locate(board, full_img)
Traceback (most recent call last):
File "C:/Users/ipetrash/Desktop/PyScripts/2048_bot/__unnecessary test code.py", line 165, in <module>
coords = pyscreeze.locate(board, full_img)
File "C:\Users\ipetrash\AppData\Local\Continuum\Anaconda3\lib\site-packages\pyscreeze\__init__.py", line 250, in locate
points = tuple(locateAll(needleImage, haystackImage, **kwargs))
File "C:\Users\ipetrash\AppData\Local\Continuum\Anaconda3\lib\site-packages\pyscreeze\__init__.py", line 121, in _locateAll_opencv
needleImage = _load_cv2(needleImage, grayscale)
File "C:\Users\ipetrash\AppData\Local\Continuum\Anaconda3\lib\site-packages\pyscreeze\__init__.py", line 103, in _load_cv2
return img_cv
UnboundLocalError: local variable 'img_cv' referenced before assignment
OK:
import pyscreeze
coords = pyscreeze.locate(board, full_img, grayscale=True)
Installing by pip into a Python 3 virtualenv on Ubuntu 14.04 installation breaks with this traceback:
Collecting Pillow (from pyautogui)
Using cached Pillow-3.2.0.zip
Collecting pyscreeze (from pyautogui)
Using cached PyScreeze-0.1.8.zip
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-build-iwkavk3q/pyscreeze/setup.py", line 6, in
version=import('pyscreeze').version,
File "/tmp/pip-build-iwkavk3q/pyscreeze/pyscreeze/init.py", line 21, in
from PIL import Image
ImportError: No module named 'PIL'
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-iwkavk3q/pyscreeze/
However if I install Pillow first, the installation works
Latest version 0.1.20 throws on import with python 2.7:
python -c 'import pyautogui'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "$PREFIX/lib/python2.7/site-packages/pyautogui/__init__.py", line 84, in <module>
import pyscreeze
File "$PREFIX/lib/python2.7/site-packages/pyscreeze/__init__.py", line 168
yield Box(x, y, needleWidth, needleHeight)
SyntaxError: 'return' with argument inside generator
Reported by a user: Windows 8.1 weirdly only lets pyautogui get a region of the top right area of the screen
A warning should be given when failing an attempt to import cv2 and numpy rather than silently failing and using the sub-optimal pure python fallback for the locateAll()
function.
I think that could have async functions prepared for async/await archtecture.
and for faster performance, it could accept others formats, in mac os the .tifff is faster than .png
This bug appears to have been introduced in version 0.1.29. When opencv is installed the locateAll methods don't work correctly, failing to find the needle image, even though it is in pixel-for-pixel present at position (0,0) in the haystack.
The pillow version finds it, but the cv2 version does not:
>>> import pyscreeze
>>> list(pyscreeze._locateAll_pillow(needleImage='corner-icon.png', haystackImage='./screenshot.png'))
[Box(left=0, top=0, width=16, height=16)]
>>> list(pyscreeze._locateAll_opencv(needleImage='corner-icon.png', haystackImage='./screenshot.png'))
[]
But the image is present in the upper left corner:
>>> import cv2
>>> needle = cv2.imread('corner-icon.png')
>>> haystack = cv2.imread('screenshot.png')
>>> (haystack[:16,:16] == needle).all()
True
# python --version
Python 3.8.16
# pip freeze
EasyProcess==1.1
entrypoint2==1.1
jeepney==0.8.0
mss==9.0.1
numpy==1.24.3
opencv-python-headless==4.7.0.72
Pillow==9.5.0
pyscreenshot==3.1
PyScreeze==0.1.29
# head -n 2 /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
This also reproduced on MacOS (Python 3.9.12).
locateOnScreen fails with win7
same code and same images
3rd party pyscreeze type stubs have been added to typeshed (by myself) https://github.com/python/typeshed/tree/master/stubs/PyScreeze
It'd be best if the stubs were part of pyscreeze itself. You should be able to use them directly from typeshed (and they should be fairly accurate). Although they also wouldn't be removed from typeshed until a PyPI release of pyscreeze includes the stubs.
Ultimately, the best scenario is to have inline typing directly, as it reduces chances of desync between stubs and implementation, and allows for easy type-checking in the CI and during development. However, due to the Python2 support requirement, inline type comments may be annoying, and will be more complicated to support multiple Python version while trying to keep typing as accurate as possible depending on what said version supports.
All the images are not present in archive and thus it is not possible to execute the tests.
Could you please adjust your MANIFEST.in to include them?
Also there are tags missing here so I can't fallback to use the github tag archive instead.
I was using pyautogui, but I thought it was better to post here as it is where pyautogui imports from.
When compiling python scripts into executable, the file generated includes the entire OpenCV library (~40MB). Which is annoying for small projects with an average of 7MB per executable, for example. Even what you need is just merely a single method, it imports everything:
from pyautogui import locateCenterOnScreen
The output file is 47MB.
It might be negligible with a project with a single executable, but I am working with a project with multiple executable and this increases the file size a lot.
Another thing is if you didn't use the confidence
option (no need of OpenCV), it also includes 40MB of useless code into executable. The only way to avoid it is to uninstall OpenCV, compile, and then reinstall it, which is quite annoying.
Hello,
I'm running CentOS 7 which requires scrot for the pyscreeze functions of pyautogui. As Scrot is no longer maintained it seems to have been removed from all repositories and the main website for Scrot is also offline, so I can't compile it from source either.
Will there be an update for linux that doesn't require scrot, or do you know of a way to get scrot installed on RHEL based systems?
Thanks in advance.
Traceback (most recent call last):
File "/usr/local/Cellar/[email protected]/3.11.1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/Users/kain/src/parser/main.py", line 36, in run
spell_scan_result = pyautogui.locateOnScreen(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pyautogui/__init__.py", line 175, in wrapper
return wrappedFunction(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pyautogui/__init__.py", line 213, in locateOnScreen
return pyscreeze.locateOnScreen(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pyscreeze/__init__.py", line 381, in locateOnScreen
if retVal or time.time() - start > minSearchTime:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'float' and 'tuple'
I am facing a problem that started with Mac OS 13.2.1 and was not happening on Mac OS 12.6.3 which that the call to pyautogui.screenshot()
is not taking a screen shot.
script to reproduce the problem:
import pyautogui
import numpy
import cv2
images = pyautogui.screenshot()
frames = numpy.array(images)
frames_RGB = cv2.cvtColor(frames, cv2.COLOR_BGR2RGB)
Please advice. Thanks!
This is error imformation:
Traceback (most recent call last):
File "C:\Users\A\Desktop\waterRPA\waterRPA.py", line 158, in
mainWork(sheet1)
File "C:\Users\A\Desktop\waterRPA\waterRPA.py", line 99, in mainWork
mouseClick(1,"left",img,reTry)
File "C:\Users\A\Desktop\waterRPA\waterRPA.py", line 13, in mouseClick
location=pyautogui.locateCenterOnScreen(img)
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyautogui_init_.py", line 175, in wrapper
return wrappedFunction(*args, **kwargs)
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyautogui_init_.py", line 207, in locateCenterOnScreen
return pyscreeze.locateCenterOnScreen(*args, **kwargs)
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyscreeze_init_.py", line 413, in locateCenterOnScreen
coords = locateOnScreen(image, **kwargs)
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyscreeze_init_.py", line 373, in locateOnScreen
retVal = locate(image, screenshotIm, **kwargs)
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyscreeze_init_.py", line 353, in locate
points = tuple(locateAll(needleImage, haystackImage, **kwargs))
File "C:\Users\A\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyscreeze_init_.py", line 229, in _locateAll_opencv
result = cv2.matchTemplate(haystackImage, needleImage, cv2.TM_CCOEFF_NORMED)
cv2.error: OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\core\src\alloc.cpp:73: error: (-4:Insufficient memory) Failed to allocate 199209624 bytes in function 'cv::OutOfMemoryError'
And the picture use to locateCenterOnScreen() just 16.5KB.But it throw OutOfMemoryError.
while Ture:
location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
if location is not None:
pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
break
print("Not found,retry after 0.1s")
time.sleep(0.1)
This error will happend after 10 times or more.
python 3.8
MouseInfo 0.1.3
numpy 1.21.4
opencv-python 4.5.4.60
Pillow 8.4.0
pip 21.3.1
PyAutoGUI 0.9.53
PyGetWindow 0.0.9
PyMsgBox 1.0.9
pyperclip 1.8.2
PyRect 0.1.4
PyScreeze 0.1.28
pytweening 1.0.4
setuptools 41.2.0
xlrd 2.0.1
Every time I run my script, I get an error at a random point in time (the program can crash on startup or minutes into running) that says windll.user32.ReleaseDC failed : return 0
. I read up on this issue thread made a while back and read it was "implemented" into the code, yet on Python 3.9.1 it simply does not seem to work, yet I tried running it on a separate Kernel (one that is not directly in cmd and thus runs the script I designed quite slowly [for reference, it's the built-in Kernel of Spyder 3.7]) with Python 3.7.6 and it seems to work perfectly fine. At this point, I have no clue what could be causing this issue nor how to fix it; any updates or help would be appreciated.
Hello! I've been stuck with this for the last couple of days, I have a PDF with some fields I need to click, the fields are light blue, so I search these using pyautogui.locateCenterOnScreen
, but as I tracked down to pyscreeze._locateAll_opencv
, I will use this on demo code
Box(left=30, top=243, width=8, height=9)
I'm glad to help if needed, but atm I don't know what to do anymore besides using matchTemplate for this exact set of needle/haystack, this might be a bug, so I guess I should open this issue
Windows 10 Pro Version 21H2
3.9.13
0.9.53
0.1.28
import pyscreeze
import cv2
def template_match(haystack, needle):
"""from: https://stackoverflow.com/questions/7853628/how-do-i-find-an-image-contained-within-an-image"""
method = cv2.TM_SQDIFF_NORMED
haystack = cv2.imread(haystack)
needle = cv2.imread(needle)
h, w = needle.shape[:2]
needle_w, needle_h = needle.shape[:2]
result = cv2.matchTemplate(needle, haystack, method)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)
x, y = minLoc
return pyscreeze.Box(x, y, needle_w, needle_h)
if __name__ == '__main__':
haystack = r".\haystack.png"
needle = r".\needle.png"
correct_box = template_match(haystack, needle)
boxes: list[pyscreeze.Box] = list(pyscreeze._locateAll_opencv(needle, haystack))
for box in boxes:
print(f"Pyscreeze matched {box}")
print(f"{correct_box = }")
I know that I can use the locateOnScreen multiple times to make it. But it'll take a lot of time in this way. And during this time the screen may change. Can I just save the current screenshot and just search in this screenshot?
Let locateAll() and other functions take Path objects.
If speed is important, install the optional opencv library (
pip install cv2
).
But cv2
does not exist on pypi. Should it be opencv-python
instead?
Is there a way to find an image based on base64 string instead of reading the file from disk?
setup.py
imports pyscreeze
to get the version info. This then fails if the dependency PIL
(Pillow
) is not already installed when setup.py is run (which may be by pip
).
Solution: put version info (and optionally any other distribution metadata) in an extra module file (e.g. version.py
, release.py
or metadata.py
) and do not import it, but read it with:
data = {}
version_info = 'pyscreeze/version.py'
exec(compile(open(version_info).read(), version_info, 'exec'), {}, data)
version = data['__version__']
BTW, from pyscreeze.version import __version__ as version
does also not work, since this will implicitly import pyscreeze/__init__.py
.
This also prevents the possible problem where setup.py
is run with an already installed version of pyscreeze and the version info is read from the installed package, rather from the directory, from which setup.py
is run.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.