Screenshot code for Tiger
-
I searched for screenshot example code, and found few solutions, and
its not clear which is the way to go.
First I found this code:
NSView *view = [window contentView];
[view lockFocus];
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
initWithFocusedViewRect:[view bounds]];
[view unlockFocus];
But various comments suggest it does not work on Tiger any more. Anyone
knows why?
Then there is Apple glGrab example code
http://developer.apple.com/samplecode/Sample_Code/Archive/Graphics/
glGrab.htm. The file was removed from Apple site - anyone knows why?
Then there is this code, that appear to be copied from glGrab.c:
http://www.cocoabuilder.com/archive/message/cocoa/2005/8/13/144256.
Then in http://www.cocoadev.com/index.pl?ScreenShotCode, there is code
base on glGrab by http://www.cocoadev.com/index.pl?MikeAsh.
Then there is this code using Carbon in
http://www.cocoadev.com/index.pl?ScreenShotCode, by
http://www.cocoadev.com/index.pl?RyanBates:
+ (NSImage *)imageWithScreenShotInRect:(NSRect)cocoaRect
{
PicHandle picHandle;
GDHandle mainDevice;
Rect rect;
NSImage *image;
NSImageRep *imageRep;
// Convert NSRect to Rect
SetRect(&rect, NSMinX(cocoaRect), NSMinY(cocoaRect),
NSMaxX(cocoaRect), NSMaxY(cocoaRect));
// Get the main screen. I may want to add support for multiple
screens later
mainDevice = GetMainDevice();
// Capture the screen into the PicHandle.
picHandle = OpenPicture(&rect);
CopyBits((BitMap *)*(**mainDevice).gdPMap, (BitMap
*)*(**mainDevice).gdPMap,
&rect, &rect, srcCopy, 0l);
ClosePicture();
// Convert the PicHandle into an NSImage
// First lock the PicHandle so it doesn't move in memory while
we copy
HLock((Handle)picHandle);
imageRep = [NSPICTImageRep imageRepWithData:[NSData
dataWithBytes:(*picHandle)
length:GetHandleSize((Handle)picHandle)]];
HUnlock((Handle)picHandle);
// We can release the PicHandle now that we're done with it
KillPicture(picHandle);
// Create an image with the representation
image = [[[NSImage alloc] initWithSize:[imageRep size]]
autorelease];
[image addRepresentation:imageRep];
return image;
}
Finally, there is this code from sticksoftwate:
http://www.sticksoftware.com/developer/Screensnap.m.txt
Maybe someone can clear the mess and explain which is the recommended
and tested way to have a screenshot on Tiger?
Best Regards,
Nir Soffer -
In my app I use code similar to
> NSView *view = [window contentView];and it works fine on all tested systems (10.2.3, 10.2.8, 10.3.5, 10.3.9,
> [view lockFocus];
> NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
> initWithFocusedViewRect:[view bounds]];
> [view unlockFocus];
10.4, 10.4.4(Intel), 10.4.5, 10.4.6). -
On Apr 24, 2006, at 6:11 AM, Dmitry Savenok wrote:
> In my app I use code similar to
>
>> NSView *view = [window contentView];
>> [view lockFocus];
>> NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
>> initWithFocusedViewRect:[view bounds]];
>> [view unlockFocus];
> and it works fine on all tested systems (10.2.3, 10.2.8, 10.3.5,
> 10.3.9,
> 10.4, 10.4.4(Intel), 10.4.5, 10.4.6).
For the sake of completeness, you can also look at the Carbon sample:
/Developer/Examples/Carbon/Magnify/
Or the source code for OSXvnc on source forge. Both of these use
QuickDraw to capture portions of the screen.
Another technique is to access the frame buffer directly using
CGDisplayBaseAddress, but that puts you more at the mercy of the
screen's configuration (display depth and such).
Finally, if you want to capture into a file, you can invoke the
command-line utility 'screencapture' from your application to grab
bits from the screen.
Scott -
On Apr 24, 2006, at 6:57 AM, Scott Thompson wrote:
>
> On Apr 24, 2006, at 6:11 AM, Dmitry Savenok wrote:
>
>> In my app I use code similar to
>>
>>> NSView *view = [window contentView];
>>> [view lockFocus];
>>> NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
>>> initWithFocusedViewRect:[view bounds]];
>>> [view unlockFocus];
>> and it works fine on all tested systems (10.2.3, 10.2.8, 10.3.5,
>> 10.3.9,
>> 10.4, 10.4.4(Intel), 10.4.5, 10.4.6).
>
> For the sake of completeness, you can also look at the Carbon sample:
>
> /Developer/Examples/Carbon/Magnify/
>
> Or the source code for OSXvnc on source forge. Both of these use
> QuickDraw to capture portions of the screen.
Note QuickDraw is considered deprecated now so I would shy away from
using any method that makes use of QuickDraw.
-Shawn -
On 26/04/2006, at 06:35, Shawn Erickson wrote:
> Note QuickDraw is considered deprecated now so I would shy away from
> using any method that makes use of QuickDraw.
That leaves us with the slow initWithViewRect:, or the example OpenGL
code that was removed from Apple site from unknown reason - and looks
like it supposed to run on PPC.
Best Regards,
Nir Soffer -
On 4/26/06, Nir Soffer <nirs...> wrote:
>
> On 26/04/2006, at 06:35, Shawn Erickson wrote:
>
>> Note QuickDraw is considered deprecated now so I would shy away from
>> using any method that makes use of QuickDraw.
>
> That leaves us with the slow initWithViewRect:, or the example OpenGL
> code that was removed from Apple site from unknown reason - and looks
> like it supposed to run on PPC.
The "initWithViewRect:" method only works in your own application, is
that what you want? Or do you want to take a screen shot of things
other then just your application? It would be better to outline
exactly what you are trying to achieve.
Assuming you want to take screen shots of things other then your own
windows/views...
Folks on the Quartz-Dev list and/or Open-GL lists likely will have
better answers for you. Anyway I believe the "right way" to do this
(outside of OpenGL) is to use the facilities provided by Quartz
Display Services [1].
To get optimal read back performance you need to align buffers to at
least a 32 byte boundary IIRC.
-Shawn
[1] <http://developer.apple.com/documentation/GraphicsImaging/Reference/Quartz_S
ervices_Ref/Reference/reference.html#//apple_ref/doc/uid/TP30001070-CH202-F
17088> -
On 4/26/06, Shawn Erickson <shawnce...> wrote:
> On 4/26/06, Nir Soffer <nirs...> wrote:
>>
>> On 26/04/2006, at 06:35, Shawn Erickson wrote:
>>
>>> Note QuickDraw is considered deprecated now so I would shy away from
>>> using any method that makes use of QuickDraw.
>>
>> That leaves us with the slow initWithViewRect:, or the example OpenGL
>> code that was removed from Apple site from unknown reason - and looks
>> like it supposed to run on PPC.
>
> The "initWithViewRect:" method only works in your own application, is
> that what you want? Or do you want to take a screen shot of things
> other then just your application? It would be better to outline
> exactly what you are trying to achieve.
>
> Assuming you want to take screen shots of things other then your own
> windows/views...
>
> Folks on the Quartz-Dev list and/or Open-GL lists likely will have
> better answers for you. Anyway I believe the "right way" to do this
> (outside of OpenGL) is to use the facilities provided by Quartz
> Display Services [1].
>
> To get optimal read back performance you need to align buffers to at
> least a 32 byte boundary IIRC.
As a follow up the best way... the way to get DMAed reads from VRAM...
is to use OpenGL.
-Shawn -
On Apr 26, 2006, at 12:17 PM, Shawn Erickson wrote:
> On 4/26/06, Shawn Erickson <shawnce...> wrote:
>> On 4/26/06, Nir Soffer <nirs...> wrote:
>>>
>>> On 26/04/2006, at 06:35, Shawn Erickson wrote:
>>>
>>>> Note QuickDraw is considered deprecated now so I would shy away
>>>> from
>>>> using any method that makes use of QuickDraw.
>>>
>>> That leaves us with the slow initWithViewRect:, or the example
>>> OpenGL
>>> code that was removed from Apple site from unknown reason - and
>>> looks
>>> like it supposed to run on PPC.
FWIW, Mike Paquette at Apple posted the glGrab code to Quartz-dev
earlier today. Interested parties can look in the archives to
retrieve that code.
Scott -
Am 26.04.2006 um 05:35 schrieb Shawn Erickson:
> On Apr 24, 2006, at 6:57 AM, Scott Thompson wrote:
>
>> On Apr 24, 2006, at 6:11 AM, Dmitry Savenok wrote:
>>
>>> In my app I use code similar to
>>>
>>>> NSView *view = [window contentView];
>>>> [view lockFocus];
>>>> NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
>>>> initWithFocusedViewRect:[view bounds]];
>>>> [view unlockFocus];
>>> and it works fine on all tested systems (10.2.3, 10.2.8, 10.3.5,
>>> 10.3.9,
>>> 10.4, 10.4.4(Intel), 10.4.5, 10.4.6).
>>
>> For the sake of completeness, you can also look at the Carbon sample:
>>
>> /Developer/Examples/Carbon/Magnify/
>>
>> Or the source code for OSXvnc on source forge. Both of these use
>> QuickDraw to capture portions of the screen.
>
> Note QuickDraw is considered deprecated now so I would shy away
> from using any method that makes use of QuickDraw.
Anyone know if any of these screenshot methods includes the cursor?
I tested the CG method, but while you can use it to create a live-
updating NSImage containing a screenshot, with sort of "optical
recursion", the cursor is not in the picture.
Cheers,
-- M. Uli Kusterer
http://www.zathras.de



