Uli's Web Site
Screen shots on the Mac
Recently I needed to do a screen saver that appears to be transparent. Trouble is, ScreenSaverEngine creates the window for you, and it's opaque. So, to work around this, I had to take a screen shot when my screen saver is loaded, and then draw that as my background.
So, how do you do a screenshot from code? Well, the theory is simple: There's a few functions in CGDirectDisplay.h to get the screen's base address, row bytes, size in pixels etc. So, you just use those to copy out your drawings.
The practice is not quite as easy. When you try to directly init an NSData with the base address pointer of your screen, it complains. You'd have to create an NSMutableData and memmove() the data to its mutableBytes. But sadly, this gives you ABGR data on an Intel Mac, which is kind of confusing to Cocoa's NSImage, which expects ARGB. Since there's no flag to tell NSImage to use a different byte ordering, you have to take a detour via CGImage.
Use a preprocessor switch on TARGET_RT_LITTLE_ENDIAN to set the kCGImageAlphaPremultipliedFirst and kCGBitmapByteOrder32Little CGBitmapInfo flags (or whatever is appropriate for the current depth CGDisplayBitsPerPixel gives you). For the "else" case (i.e. big-endian on PPC), specify kCGImageAlphaPremultipliedFirst and default byte order.
Now, the CGImage is created pretty easily, but you'll have to notice that it refers to the screen buffer directly, and thus does "live updates" while you're doing screen shots. So, saving this away is pretty pointless. So, in the end, you'll have to create an NSImage of the appropriate size and use CGContextDrawImage to make an unchanging copy, and that you can save away in a movie or whatever.
If you're a Carbon coder, you might even be able to use the CGImage directly with the QuickTime APIs, but I haven't tried that (yet).
Also, be wary of keeping around the CGImage: you'll get a royal pixel massacre if someone changes the screen depth or size and you then use it again. So, you may want to sign up for some display size change notifications etc.
Created: 2006-12-12 @960 Last change: 2024-02-22 @281 | Home | Admin | Edit
© Copyright 2003-2024 by M. Uli Kusterer, all rights reserved.