Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
Hi Guys,

I am new to developing on the Mac platform. I am trying to take a screenshot using OpenGL and then paste the resulting image to the paste board. My code runs but nothing ends up in the paste board. Could someone possibly point me in the right direction? I can't figure out why the following code wont work. Any advice would be greatly appreciated! Thanks!

Code:
CGDirectDisplayID display = CGMainDisplayID();
CGRect srcRect;
srcRect.origin.x = 0;
srcRect.origin.y = 0;
srcRect.size.height = 800;
srcRect.size.width = 600;
	
	
//grab screenshot via opengl and return image as CGImageRef
CGImageRef ref= grabViaOpenGL(display, srcRect);
	
size_t pixelsWide = CGImageGetWidth(ref);
size_t pixelsHigh = CGImageGetHeight(ref);
	
 int bitmapBytesPerRow   = (pixelsWide * 4);
 int bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
	
//convert CGImageRef to CGContextRef
CGContextRef cgctx = CreateARGBBitmapContext(ref);
	

	
	// Get image width, height. We'll use the entire image.
    size_t w = CGImageGetWidth(ref);
    size_t h = CGImageGetHeight(ref);
    CGRect rect = {{0,0},{w,h}};
	
    // Draw the image to the bitmap context. Once we draw, the memory
    // allocated for the context for rendering will then contain the
    // raw image data in the specified color space.
    CGContextDrawImage(cgctx, rect, ref);
	
    // Now we can get a pointer to the image data associated with the bitmap
    // context.
    void *data = CGBitmapContextGetData (cgctx);
    if (data != NULL)
    {

OSStatus err = noErr; 
		PasteboardRef theClipboard; 
		CFDataRef           imageData = NULL; 
		
//create pasteboard
		err = PasteboardCreate( kPasteboardClipboard, &theClipboard ); 
		err = PasteboardClear( theClipboard );// 1 
		PasteboardSynchronize( theClipboard );// 2 
		
//create CFDataRef from image
		imageData = CFDataCreate( kCFAllocatorDefault, (UInt8 *)data, bitmapByteCount);
		
		//paste image to clipboard in tiff format
		err = PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, CFSTR("public.tiff"), imageData, 0 ); 
		CFRelease( imageData );
}
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Could someone possibly point me in the right direction? I can't figure out why the following code wont work. Any advice would be greatly appreciated! Thanks!

Use the debugger, step through the code line by line to determine where it's failing. If don't know how to do that, throw up simple printfs() to determine what variables are NULL/invalid.
 

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
Use the debugger, step through the code line by line to determine where it's failing. If don't know how to do that, throw up simple printfs() to determine what variables are NULL/invalid.

Thanks for the reply. I went ahead and stepped through my code and I found that all of my objects were fine, however that the call to PasteboardSynchronize( theClipboard ); was generating an error. So I took that line out and everything appeared to work. When I pasted the results to the PasteBoardPeeker application I got this and the paste never shows anything in the paintbrush application if I paste.

PasteboardRef: 1110864 ItemCount: 1
Index: 1 item ID: 1
"public.tiff"
"NeXT TIFF v4.0 pasteboard type"
'TIFF' ______ 1920000

however, when I copy and paste an image from paintbrush it shows up in pasteboardpeeker as


PasteboardRef: 1110864 ItemCount: 1
Index: 1 item ID: 789514
"public.tiff"
"NeXT TIFF v4.0 pasteboard type"
'TIFF' ______ 1434574 MM * D

"com.apple.pict"
"Apple PICT pasteboard type"
'PICT' ______ 1434650 V H H V V


So it seems that it has TIFF and PICT data. I guess I just don't understand the format that I need to save the image as in the pasteboard. Is there somewhere where I can get more information on how to copy image data to the pasteboard properly? I have looked through the apple dev site source code and documentation and all I can find is information pertaining to copy text data to the clipboard.

Thanks,
Greg
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I honestly have no idea on this, but from reading some of the reference material, MAYBE NSBitmapImageRep with -initWithCGImage:, then -TIFFRepresentation will help. You'll end up with an NSData object with the TIFF representation. Maybe sending the results of -bytes from there to the pasteboard will work out better, but this is all a big shot in the dark.

-Lee
 

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
I honestly have no idea on this, but from reading some of the reference material, MAYBE NSBitmapImageRep with -initWithCGImage:, then -TIFFRepresentation will help. You'll end up with an NSData object with the TIFF representation. Maybe sending the results of -bytes from there to the pasteboard will work out better, but this is all a big shot in the dark.

-Lee

Yea this would actually work if I was using cocoa. I did a demo using cocoa and it worked, but I am forced to use Carbon as I am building this in a director Xtra and I don't think I have the option to combine the use of carbon and cocoa.

If it can be done in Cocoa it must be possible in Carbon. I just can't find any documentation on putting images into the pasteboard.
 

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
Ok I was able to export the screenshot image to a file by using this function, but I can't figure out for the life of me how to convert the CGImageRef into a CFData object that is truly in a TIFF format and then paste it into the pasteboard.

Does anyone know how I can take a CGImageRef object and convert it to a TIFF then store it in a CFData object?

Thanks,
void ExportImage(CGImageRef image)
{
CFURLRef url = CFURLCreateWithString( NULL, CFSTR("ExportPNGTest.png"), NULL);

CFStringRef type = kUTTypePNG; //public.png
size_t count = 1;
CFDictionaryRef options = NULL;
CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url, type, count, options);

CGImageDestinationAddImage(dest, image, NULL);

CGImageDestinationFinalize(dest);
CFRelease(dest);
}
 

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
Well finally after two weeks of intense searching on google I figured out a way using ImageIO to take a CGImageRef and turn into a TIFF image suitable for being pasted onto the pasteboard!! YES!

Thanks to everyone who responded!

Cheers,
Greg
 

revg

macrumors newbie
Original poster
Aug 14, 2008
9
0
Here is the solution

Code:
void copyCGImageRefToPasteboard(CGImageRef ref)
{
	OSStatus err = noErr; 
	PasteboardRef theClipboard; 
		
	err = PasteboardCreate( kPasteboardClipboard, &theClipboard ); 
	err = PasteboardClear( theClipboard );// 1 
		
	CFMutableDataRef url = CFDataCreateMutable(kCFAllocatorDefault, 0);
		
	CFStringRef type = kUTTypeTIFF;
	size_t count = 1; 
	CFDictionaryRef options = NULL;
	CGImageDestinationRef dest = CGImageDestinationCreateWithData(url, type, count, options);
	CGImageDestinationAddImage(dest, ref, NULL);
	CGImageDestinationFinalize(dest);

	err = PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1, type, url, 0 ); 
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.