Closed latenitefilms closed 7 years ago
What does hs.screen:snapshot():setSize{ w = 1920, h = 1080 }:saveToFile("/path/to/file.jpg", "jpg")
give you?
@asmagill - Yeah, I tried that.
Using:
hs.screen.primaryScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test.jpg", "jpg")
...still returns an file that is the full resolution/size of the screen.
I assume because saveToFile
"Saves image at its original size"?
I'll have to look into it... setSize
is supposed to return brand new image object (for backwards compatibility reasons) at the new size, so what finally makes it into saveToFile
is no longer the original image...
I know setSize
works when using the image object in menus, etc. but since saveToFile
uses a bitmap representation, it may be bypassing some of the NSImage attributes that aren't applied directly to the source data but rather to how that source data is "shared" with code accessing it as an NSImage
.
Try pull #1373 with hs.screen:snapshot():setSize{ w = 1920, h = 1080 }:saveToFile("/path/to/file.jpg", "jpg")
and see if that's better.
I'm not sure that we can easily get into modifying the images actual dpi without really delving into CGImage and/or CIImage/CIFilter territory, and while I'd like to sometime because there are some really cool things you can do with images in there, I don't see having the time in the near future.
(if anyone else wants to take this on, I made a stab at the beginning of a module for CIFilter awhile back that can be found at https://github.com/asmagill/hammerspoon_asm/blob/master/cifilter/ that you're more then welcome to start from or throw away entirely)
Nope - no change unfortunately:
Retina display?
When I do the save specifying the size of 1920x1080, I get an image at 3456x2160 that is 729k When I do the save with no size method included, the image is at 6720x4200 that is 1.8 MB
e.g.
> hs.screen.primaryScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test.jpg", "jpg")
true
> hs.screen.primaryScreen():snapshot():saveToFile("~/Desktop/test2.jpg", "jpg")
true
Let me see if we can remove the scaling factor easily...
Yes, MacBook Pro (Retina, 15-inch, Early 2013).
Thanks so much for all your help @asmagill !
Ok, try the updated pull now, the examples I used were:
hs.screen.mainScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test.jpg", "jpg"),
hs.screen.mainScreen():snapshot():saveToFile("~/Desktop/test2.jpg", "jpg"),
hs.screen.mainScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test3.jpg", true, "jpg"),
hs.screen.mainScreen():snapshot():saveToFile("~/Desktop/test4.jpg", true, "jpg")
and I got files basically as I expected (the third one was actually 1727x1080, but that's to be expected since setSize
wasn't set to absolute so it scaled it proportionally to fit.)
Sorry! I get this:
What line from the hs.image internal.m file is on the callback stack?
Don't have access to a 5k monitor, so not sure what kind of issues that might introduce memory wise... what does hs.inspect(hs.screen.mainScreen():currentMode())
report when that screen has the focused window? How large of a file (dimensions and size) does hs.screen.mainScreen():snapshot():saveToFile("path", "jpg")
generate (i.e. no size changes, no pixel scaling)
This is just on my laptop - not my iMac.
> hs.inspect(hs.screen.mainScreen():currentMode())
2017-05-05 10:14:19: -- Loading extension: inspect
2017-05-05 10:14:19: -- Loading extension: screen
{
desc = "1680x1050@2x",
h = 1050,
scale = 2.0,
w = 1680
}
When trying to run:
hs.screen.mainScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test.jpg", "jpg"),
hs.screen.mainScreen():snapshot():saveToFile("~/Desktop/test2.jpg", "jpg"),
hs.screen.mainScreen():snapshot():setSize({ w = 1920, h = 1080 }):saveToFile("~/Desktop/test3.jpg", true, "jpg"),
hs.screen.mainScreen():snapshot():saveToFile("~/Desktop/test4.jpg", true, "jpg")
I get:
I can confirm it will crash with this when run from within XCode.
I don't know enough about XCode and how it changes/manipulates things to even begin to try and debug this, so let me know if it works for you when running as a standalone application.
Ah, right, no worries. I know absolutely nothing about Xcode - so didn't even think to try it outside of Xcode.
It no longer crashes!
test.jpg = 3840x2160 @ 144 dpi test2.jpg = 3840x2160 @ 144 dpi test3.jpg = 1920x1080 @ 72 dpi test4.jpg = 1920x1080 @ 72 dpi
Thanks @asmagill !!
If someone more familiar with how XCode modifies the environment when a program is being run from within it wants to tackle the crash described above, please feel free to reopen this (and describe the issue so we can all learn from it!).
I haven't tried to reproduce this yet, but note that it's not a crash, it's detecting that it's being run in a debugger and is intentionally popping out control to the debugger because it is suspicious that something just tried to malloc()
134MB.
While 134MB does seem fairly crazy, if you look in the stacktrace, it's fetching a TIFF representation of the image.
Assuming you're running your 5K iMac at the native @2x resolution (2560x1440) the actual framebuffer is 5120x2880, which at 32bit would make for 59MB of raw image data, but it's not 32bit, because the display is 10bits per channel (not 100% sure if the alpha channel in a screenshot would also get 10bits) which puts the image data closer to 74MB and that gets us within 2x of the malloc()
size.
All of that is to say, while it's perhaps surprising to see 134MB allocated for a screenshot, it's perhaps not unreasonable :)
It would be awesome if you could customise the output size and resolution (i.e. I want to output my 5K iMac screen to 1920x1080 @ 52dpi).