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

[Question] I try to take the screen on mac os but dont works #44

Open
iddar opened this issue Jun 3, 2022 · 7 comments
Open

[Question] I try to take the screen on mac os but dont works #44

iddar opened this issue Jun 3, 2022 · 7 comments

Comments

@iddar
Copy link

iddar commented Jun 3, 2022

I try to take the screen on mac os (run on MacBook Pro M1), I follow the sample code here

But the result is

screenshot

I test in Linux, the code works great.

Do you have any idea what could be going on?

@rjooske
Copy link

rjooske commented Mar 28, 2023

I think I figured out why this happens.
It seems that on macOS (as far as I could check), the definition of "stride" is somewhat different from what it's assumed to be in the readme, example code, etc.

Let's say we have a screen whose resolution is 4x3.
The example code assumes that the incoming frame buffer looks like this (newlines inserted for legibility):

B G R A B G R A B G R A B G R A ? ? ? ? ? ? ? ?
B G R A B G R A B G R A B G R A ? ? ? ? ? ? ? ?
B G R A B G R A B G R A B G R A ? ? ? ? ? ? ? ?

where B, G, R, and A represent blue, green, red, and alpha value, and ? represents junk data.
In this case, we can see that:

  • The length of the buffer is 72
  • The "stride" is (buffer length) / (screen height) = 24

However on macOS, the incoming frame buffer actually looks like this:

B G R A B G R A B G R A B G R A
B G R A B G R A B G R A B G R A
B G R A B G R A B G R A B G R A
? ? ? ? ? ? ? ? ? ?

Now we're in a slightly different situation.
The length of the buffer now is 58, and the "stride" is 58/3 = 19.333... = 19 (rounded down here).
Because of this, the example code interprets the frame buffer incorrectly like so:

B G R A B G R A B G R A B G R A B G R
A B G R A B G R A B G R A B G R A B G
R A B G R A B G R A ? ? ? ? ? ? ? ? ?
?

which explains why @iddar's screenshot got skewed and have alternating colors every line.


Fixing this issue in the example code on macOS is pretty easy.
Just replace this line:

let stride = buffer.len() / h;

to this:

let stride = w * 4;

Glitched screenshot that I could reproduce on my machine:
bad

And the screenshot I took with the fix applied:
good

It would be awesome if we can have something like an iterator that can iterate over non-junk [B, G, R, A] pairs regardless of the platform!

@rjooske
Copy link

rjooske commented Mar 28, 2023

I forgot to mention that my machine's got M1 in it too.
16" M1 Max Macbook Pro with 32GB RAM, to be precise.

@arb000r
Copy link

arb000r commented Apr 2, 2023

I can't seem to get an appropriate screenshot even after the stride change

@arb000r
Copy link

arb000r commented Apr 3, 2023

@rjooske After testing for a bit it looks like when I use a monitor the output is a clear image but when its just the macbook screen it looks like this - Any ideas?

screenshot

@rjooske
Copy link

rjooske commented Apr 11, 2023

@1saf That's interesting. I also have an external monitor (Dell S2722QC, for the record) and did some more digging around. What I found is the following:

Built-in monitor? Default scaling? Correct image? (with the previously mentioned fix)
yes yes yes
yes no no
no yes yes
no no yes

It seems that the screenshot gets messed up only when you take the screenshot of the built-in monitor, and you use non-default scaling. Although the result could be different depending on what monitor you use. (I only have one so I can't test it now)

My initial guess was that Capturer.width() and Capturer.height() might be returning some weird dimensions when the monitor is set to use non-default scaling, but they do give correct values as far as I could test.

@arb000r
Copy link

arb000r commented Jun 15, 2023

@1saf That's interesting. I also have an external monitor (Dell S2722QC, for the record) and did some more digging around. What I found is the following:

Built-in monitor? Default scaling? Correct image? (with the previously mentioned fix)
yes yes yes
yes no no
no yes yes
no no yes
It seems that the screenshot gets messed up only when you take the screenshot of the built-in monitor, and you use non-default scaling. Although the result could be different depending on what monitor you use. (I only have one so I can't test it now)

My initial guess was that Capturer.width() and Capturer.height() might be returning some weird dimensions when the monitor is set to use non-default scaling, but they do give correct values as far as I could test.

So no way to work around it? :'( I tried different solutions in regards to scaling.

@stolinski
Copy link

I'm using built in monitor, default scaling and am able to get a good picture, but it's not a high res capture.

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

4 participants