Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect screen size on Mac #33

Open
luojxxx opened this issue May 13, 2015 · 24 comments
Open

Incorrect screen size on Mac #33

luojxxx opened this issue May 13, 2015 · 24 comments

Comments

@luojxxx
Copy link

luojxxx commented May 13, 2015

Hi!

So I have a MacBook Pro retina running windows 8.1 on bootcamp.

And the actual screen resolution is 2880 x 1800, but pyautogii.size() returns 1920 x 1080.

I can't seem to find documentation about how to set these values nor have I been able to guess them.

I believe it has to do with the retina scaling, but as of right now the pointer is constantly thrown off.

Any help would be greatly appreciated!

@asweigart
Copy link
Owner

Is this similar to issue #12 ? If so, this has been fixed and you should update pyautogui by running:

pip3 install -U pyautogui

@luojxxx
Copy link
Author

luojxxx commented May 14, 2015

Hmmm…. I’m using python 2.7 and it’s on the bootcamp Windows 8.1 side of a retina macbook pro. I’m not sure how that’d work out...

On May 14, 2015, at 12:59 AM, Al Sweigart notifications@github.com wrote:

Is this similar to issue #12 #12 ? If so, this has been fixed and you should update pyautogui by running:

pip3 install -U pyautogui

Reply to this email directly or view it on GitHub #33 (comment).

@PaigeVG
Copy link

PaigeVG commented Aug 2, 2016

Hey guys. I had a similar problem using this library on Windows 10 on a 4k display - In my case, I found it was related to DPI scaling not being accounted for.

I solved the issue by adding the following to my script:

from ctypes import windll
user32 = windll.user32
user32.SetProcessDPIAware()

There may be a similar bit of functionality for MacOS.

@callmewhy
Copy link

@starbadger You solved my issue, it works on Windows 10, thanks.

@balajimulik
Copy link

@starbadger Thank you, solved my issue on Windows 7 as well!

@yabbas
Copy link

yabbas commented Mar 3, 2017

Just put the issue up on Pillow - ty for the fix @starbadger - worked a treat!

@asweigart asweigart changed the title Incorrect screen size Incorrect screen size on Mac Mar 19, 2017
@kasperschnack
Copy link

kasperschnack commented Dec 22, 2017

Pyautogui uses screencaps to find the location of stuff on the screen. The problem on macs with a retina display is that the screen output have double the number of pixels, to take advantage of the system’s greater pixel density for a crisper image.Therefore, when you take a screenshot, you get an image containing double the number of pixels than the same image from a non-retina Mac.
source

One work around is to change the yield of pyscreeze._locateAll_opencv and pyscreeze._locateAll_python (the pyautogui source code):

pyscreeze._locateAll_opencv:
change
yield (x, y, needleWidth, needleHeight) to

if subprocess.call("system_profiler SPDisplaysDataType | grep -i 'retina'", shell= True) == 0: 
    yield (int((matchx + region[0])*0.5), int((y + region[1])*0.5), int(needleWidth*0.5), int(needleHeight*0.5))
  else:
    yield (matchx + region[0], y + region[1], needleWidth, needleHeight)

pyscreeze._locateAll_python:
change
yield (matchx + region[0], y + region[1], needleWidth, needleHeight)
to

if subprocess.call("system_profiler SPDisplaysDataType | grep -i 'retina'", shell= True) == 0: 
    yield (int((matchx + region[0])*0.5), int((y + region[1])*0.5), int(needleWidth*0.5), int(needleHeight*0.5))
else:
    yield (matchx + region[0], y + region[1], needleWidth, needleHeight)

@domluther
Copy link

domluther commented Jan 6, 2018

@kasperschnack I tried that fix, and got...

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyscreeze/__init__.py", line 272, in locateOnScreen
    retVal = locate(image, screenshotIm, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyscreeze/__init__.py", line 256, in locate
    points = tuple(locateAll(needleImage, haystackImage, **kwargs))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pyscreeze/__init__.py", line 231, in _locateAll_python
    yield (int((matchx + region[0])*0.5), int((y + region[1])*0.5), int((needleWidth, needleHeight))*0.5)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'tuple'

@kasperschnack
Copy link

kasperschnack commented Jan 6, 2018

@domluther try changing int((needleWidth, needleHeight))*0.5) (in both files) to int(needleWidth*0.5), int(needleHeight*0.5) - does that do the trick?

@domluther
Copy link

@kasperschnack Yes, it does! Thanks. Is there any particular reason why on one of them you've done the *0.5 inside the parentheses and the other outside??

@kasperschnack
Copy link

@domluther that was a mistake - have fixed it now :)

@jerb6
Copy link

jerb6 commented Aug 7, 2018

Hello !
Please, how do I modify pyscreeze._locateAll_opencv and pyscreeze._locateAll_python ?

@kasperschnack
Copy link

kasperschnack commented Aug 7, 2018

Hello @jerb6.

You can modify the module directly.

If you're not sure where it is located you can find the location open the python repl in your terminal and run the following commands:

import pyscreeze
print(pyscreeze.__path__)

This should reveal the location of the .py file. Edit it, save it and you should be good to go :).

If you use an IDE like pycharm, you should be able to find the file by cmd+clicking on the import in your script.

@jerb6
Copy link

jerb6 commented Aug 7, 2018

oh ! okay thank you very much @kasperschnack !!
Yes, I opened with pycharm.

But I have another problem.. Sorry for bothering you, I'm a complete beginner !
I can't modify yield (x, y, needleWidth, needleHeight) and yield (matchx + region[0], y + region[1], needleWidth, needleHeight)..

I says : failed to change read-only status for the following files :
/library/Frameworks/Python.frameworks/Versions/3.7/lib/python3.7/site-packages/pyscreeze/ __ init __ .py

@kasperschnack
Copy link

kasperschnack commented Aug 7, 2018

@jerb6

It's wierd that your python packages/modules are installed in your /library directory I think. Normally they'd be installed in your $HOME-dir. I expect you're using the python installation that ships default with Mac OS. I believe that is the reason for the files being read-only. If you install Python with homebrew(which I would recommend you do) you probably wouldn't have this problem, although you might have to reinstall your packages.

You might be able to change it from the IDE though without doing any reinstalls
Open the file(/library/Frameworks/Python.frameworks/Versions/3.7/lib/python3.7/site-packages/pyscreeze/ __ init __ .py) in pycharm and do the following:
On the main menu, choose File -> Make File Writable.

@jerb6
Copy link

jerb6 commented Aug 7, 2018

@kasperschnack I actually changed all directories on "read and write" because all was on "read only" !
Now it work ! And your modifications works too ! Thank you so much !

@ghost
Copy link

ghost commented Nov 23, 2018

I changed the lines of source code like @kasperschnack suggested, but nothing different is happening. I tried changing 0.5 to different factors so see if it had any effect but I still have pyautogui.size returning half of my resolution 1280 x 800 (instead of 2560 x 1600). Maybe I changed the code incorrectly and did something wrong with the indentation (I'm new to programming) or it's the fact that I'm running OSX 10.14.1 Mojave. It's like none of the saved changes are applied.

The changed code looks like this:

schermafbeelding 2018-11-23 om 17 47 19

and:

schermafbeelding 2018-11-23 om 17 47 54

Hopefully anyone can help me solve this issue!

@kasperschnack
Copy link

kasperschnack commented Nov 23, 2018

I have to admit it's been a long while since if looked at this issue - but isn't 1280 x 800 is what you want? Have you tried out moving the cursor around using the library to see if it behaves as you'd expect?

@ghost
Copy link

ghost commented Nov 23, 2018

The problem is that I want to program python to take partial screenshots, which I program according to the pixel coordinates of my screen. For example, when using photoshop to find a specific spot on a full screenshot, the most right bottom pixel has coordinates 2560 x 1600. However, when I put my cursor at the right bottom of my screen and locate the coordinates with pyautogui it returns a value of 1280 x 800. I could work my way around it by dividing all coordinates by 2 for pyautogui functions, but your solution seemed more convenient for me. Unfortunately though I can not get it right.

@BenRoe
Copy link

BenRoe commented Oct 11, 2019

Unfortunately the check subprocess.call("system_profiler SPDisplaysDataType | grep -i 'retina' is not working on OSX Mojave 10.14.6
Any other ideas how to check if it is a retina?

@huni1023
Copy link

huni1023 commented Jul 7, 2021

i might be too late..
i suffer from the same issue with you guys..

i just solve this issue using the code below.

[problematic code]

pdf_con = pg.locateCenterOnScreen(
            f'{os.getcwd()[:-23]}/코드개발/pdf_loc5.png',
            # f'{os.getcwd()[:-23]}/코드개발/save.png', 
            grayscale=True,
            confidence=0.8
        )
pg.click(pdf_con)

[imporved code]

pdf_con = pg.locateCenterOnScreen(
            f'{os.getcwd()[:-23]}/코드개발/pdf_loc5.png',
            # f'{os.getcwd()[:-23]}/코드개발/save.png', 
            grayscale=True,
            confidence=0.8
        )
pg.click(pdf_con[0]/2, pdf_con[1]/2) # the reason of resolution

env
python 3.8
monitor: dell 4k (3840 x 2160)

@damanc7
Copy link

damanc7 commented Aug 6, 2021

i might be too late..
i suffer from the same issue with you guys..

i just solve this issue using the code below.

[problematic code]

pdf_con = pg.locateCenterOnScreen(
            f'{os.getcwd()[:-23]}/코드개발/pdf_loc5.png',
            # f'{os.getcwd()[:-23]}/코드개발/save.png', 
            grayscale=True,
            confidence=0.8
        )
pg.click(pdf_con)

[imporved code]

pdf_con = pg.locateCenterOnScreen(
            f'{os.getcwd()[:-23]}/코드개발/pdf_loc5.png',
            # f'{os.getcwd()[:-23]}/코드개발/save.png', 
            grayscale=True,
            confidence=0.8
        )
pg.click(pdf_con[0]/2, pdf_con[1]/2) # the reason of resolution

env
python 3.8
monitor: dell 4k (3840 x 2160)

Thanks so much, this worked for me!

@dreyign
Copy link

dreyign commented Apr 11, 2023

I have the same problem here that I cannot solve. I'm using a Macbook as well, and when I run this code, it screenshots the whole screen. How do I make it so it is only a part of the screen? I understand this is a retina problem. I also ran this code to a windows computer and it worked fine when I changed to fit the pixels of the windows.

#Screenshot for Region pyautogui.screenshot(f"{region}_{tab}_SOM.png", region = (320,337,519,439))

@mhluska
Copy link

mhluska commented Jun 19, 2023

Running into this on a MacBook now. How is this an open issue from 2015? 🤯

tubaman pushed a commit to tubaman/pyscreeze that referenced this issue Aug 4, 2023
tubaman pushed a commit to tubaman/pyscreeze that referenced this issue Aug 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests