how to copy image to pasteboard, carbon?

Discussion in 'Mac Programming' started by revg, Aug 14, 2008.

  1. revg macrumors newbie

    Joined:
    Aug 14, 2008
    #1
    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 );
    }
    
    
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    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.
     
  3. revg thread starter macrumors newbie

    Joined:
    Aug 14, 2008
    #3
    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
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    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
     
  5. revg thread starter macrumors newbie

    Joined:
    Aug 14, 2008
    #5
    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.
     
  6. revg thread starter macrumors newbie

    Joined:
    Aug 14, 2008
    #6
    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);
    }
     
  7. revg thread starter macrumors newbie

    Joined:
    Aug 14, 2008
    #7
    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
     
  8. revg thread starter macrumors newbie

    Joined:
    Aug 14, 2008
    #8
    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 ); 
    }
    
    
     

Share This Page