Hello,
I am moving my code from GLUT to Cocoa (where I am a newbie), but I really like that GLUT on OSX allows you to copy a screenshot to the pasteboard just hitting cmd-c. The code below does that in a method belonging to a subclass of NSOpenGLView. It is largely a patchwork of ideas, which I found online.
Q: Could this have been achieved simpler? In particular, without resorting to a low level for loop and perhaps just cloning the first image rather than constructing a new bitmap image? Spawning a new process, I could probably do it with just a few lines, but that would probably be a rather heavy operation.
Thanks
Andreas
-(IBAction)save_window_to_pasteboard:(id)sender
{
NSPasteboard *pb = [NSPasteboard generalPasteboard];
// Telling the pasteboard what type of data we're going to send in
[pb declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePNG,nil] owner:self];
NSRect backRect = [self convertRectToBacking: [self bounds]];
NSSize sz;
sz.width = NSWidth(backRect);
sz.height = NSHeight(backRect);
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
pixelsWide: sz.width
pixelsHigh: sz.height
bitsPerSample: 8
samplesPerPixel: 3
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: 0 // indicates no empty bytes at row end
bitsPerPixel: 0];
glReadBuffer(GL_FRONT);
int bytesPerRow = [rep bytesPerRow];
glPixelStorei(GL_PACK_ROW_LENGTH, 8*bytesPerRow/[rep bitsPerPixel]);
glReadPixels(0, 0, NSWidth(backRect), NSHeight(backRect), GL_RGB, GL_UNSIGNED_BYTE, [rep bitmapData]);
NSBitmapImageRep* flipped = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
pixelsWide: sz.width
pixelsHigh: sz.height
bitsPerSample: 8
samplesPerPixel: 3
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: 0 // indicates no empty bytes at row end
bitsPerPixel: 0];
for(int j=0; j< sz.height; ++j)
for(int i=0;i<sz.width;++i)
{
NSUInteger pixels[4];
[rep getPixel: pixels atX:i y:j];
[flipped setPixel: pixels atX:i y:sz.height-j];
}
// Converting the representation to PNG and sending it to the pasteboard (with type indicated)
[pb setData:[flipped representationUsingType:NSPNGFileType properties:nil] forType:NSPasteboardTypePNG];
}