Basically I'm using locateOnScreen()
function, which is from pyautogui
to read an image and then find in the screen by:
import os
import pathlib
import pyautogui
Image = os.path.join(os.path.sep, pathlib.Path(__file__).parent.resolve(), 'static', 'img', 'game', 'image-btn.png')
if pyautogui.locateOnScreen(BossImg, grayscale=True, confidence=0.95) != None:
print(True)
The code above works prety fine, the problem is when some users, even me because my native language is Portuguese and we have special characters in the language, and we might have some in a folder name.
Let's use this example:
In english:
C:\Users\guilh\Desktop\Folder
In Portuguese:
C:\Users\guilh\Área de Trabalho\Folder
So for some cases when we get a folder with accented characters, I'm getting the error:
Failed to read C:\Users\guilh\Área de Trabalho\Folder\image-btn.png because file is missing, has improper permissions, or is an unsupported or invalid format
But why am I gettig this error with special characters if I'm passing the path correctly with pathlib
and os
? If I run the same script in the English
example, works perfectly.
After digging a bit in the source code of PyAutoGUI
on Github, it appears that PyScreeze
is used to detect an element on the screen from an image of it, and it uses openCV's imread()
function to load the image.
cv2.imread()
currently does not support pathnames containing Non-ASCII characters on Windows.
A pull-request has already been opened on the PyScreeze repository to use cv2.imdecode()
instead of cv2.imread()
.
To fix this issue while waiting for the support for non-ASCII characters,
The first option would be to modify the PyScreeze
package installed (This can be annoying if anyone needs to be able to run the script easily from their computer).
- Identify the location of the PyScreeze
module:
python -c "import pyscreeze; print(pyscreeze.__path__)"
- Modify __init__.py
located in this folder:
Line 21,
import numpy as np
Line 166,
img_cv = cv2.imdecode(np.fromfile(img, dtype=np.uint8), LOAD_GRAYSCALE)
Line 168,
img_cv = cv2.imdecode(np.fromfile(img, dtype=np.uint8), LOAD_COLOR)
- Finally install numpy
pip install numpy
As @SiP explained, Another possibility could be to copy the image to a temporary folder.
Something like that:
import os
import pathlib
import tempfile
import shutil
import pyautogui
Image = os.path.join(os.path.sep, pathlib.Path(__file__).parent.resolve(), 'static', 'img', 'game', 'image-btn.png')
temp_path = os.path.join(tempfile.gettempdir(), "file_name_in_ascii")
shutil.copy2(Image, temp_path)
if pyautogui.locateOnScreen(temp_path, grayscale=True, confidence=0.95) is not None:
print(True)