Reputation: 12766
I am using the code from this site to copy an image file to clipboard. This is the full source code
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>
BOOL copy_to_clipboard(NSString *path)
{
// http://stackoverflow.com/questions/2681630/how-to-read-png-image-to-nsimage
NSImage * image;
if([path isEqualToString:@"-"])
{
// http://caiustheory.com/read-standard-input-using-objective-c
NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
image = [[NSImage alloc] initWithData:[input readDataToEndOfFile]];
}else
{
image = [[NSImage alloc] initWithContentsOfFile:path];
}
// http://stackoverflow.com/a/18124824/148668
BOOL copied = false;
if (image != nil)
{
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents];
NSArray *copiedObjects = [NSArray arrayWithObject:image];
copied = [pasteboard writeObjects:copiedObjects];
[pasteboard release];
}
[image release];
return copied;
}
int main(int argc, char * const argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if(argc<2)
{
printf("Usage:\n\n"
"Copy file to clipboard:\n ./impbcopy path/to/file\n\n"
"Copy stdin to clipboard:\n cat /path/to/file | ./impbcopy -");
return EXIT_FAILURE;
}
NSString *path= [NSString stringWithUTF8String:argv[1]];
BOOL success = copy_to_clipboard(path);
[pool release];
return (success?EXIT_SUCCESS:EXIT_FAILURE);
}
When I run the compiled binary with a PNG file, I get this error
$ ~/bin/imgbcopy prof/combined.png
2017-10-25 16:24:50.373 imgbcopy[80618:4292276] -[NSPasteBoard _setData:forType:index:usesPboardTypes:] returns false. Type: public.tiff, index: 0 class: NSImage.
Copying the PNG image from bash pipe also fails
$ cat prof/combined.png | ~/bin/imgbcopy -
2017-10-25 16:27:52.856 imgbcopy[80690:4293881] -[NSPasteBoard _setData:forType:index:usesPboardTypes:] returns false. Type: public.tiff, index: 0 class: NSImage.
Testing with it another random PNG screenshot works fine. I notice the error message above says Type: public.tiff
. The PNG was initially converted from SVG using ImageMagic.
What is the problem with the code, or is it a malformed PNG?
Upvotes: 1
Views: 1131
Reputation: 359
I did some tests and the results are quite remarkable.
First test:
NSData *imageData = [NSData dataWithContentsOfFile:[@"~/Downloads/combined.png" stringByExpandingTildeInPath]];
NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
[pasteBoard clearContents];
NSPasteboardItem *pasteboardItem = [[NSPasteboardItem alloc] init];
[pasteboardItem setData:imageData forType:NSPasteboardTypePNG];
NSLog(@"Write result: %i", [pasteBoard writeObjects:@[pasteboardItem]]);
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[@"~/Downloads/combined.png" stringByExpandingTildeInPath]];
NSUInteger length = [[image TIFFRepresentation] length];
NSLog(@"%f MB (%lu)", length / 1000.0 / 1000.0, length);
[pasteBoard writeObjects:@[image]];
Output:
2017-11-30 15:57:53.317349+0100 Lolo[4927:639480] Write result: 1
2017-11-30 15:57:54.831260+0100 Lolo[4927:639480] 347.824566 MB (347824566)
2017-11-30 15:57:55.293900+0100 Lolo[4927:639480] -[NSPasteBoard _setData:forType:index:usesPboardTypes:] returns false. Type: public.tiff, index: 1 class: NSImage.
I could write the image as PNG data to the pasteboard. The NSImage object can't be written like in your case. NSImage objects store themselves in multiple formats including TIFF data, so just to test I print the size of the image data it would write to the pasteboard. It's 347.824566 MB, so that might be a bit to big.
Second test:
NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
NSData *data = [pasteBoard dataForType:NSPasteboardTypeTIFF];
float length = [data length];
NSLog(@"%f MB (%f) - %@ - %@", length / 1000.0 / 1000.0, length, data, [pasteBoard types]);
Output:
2017-11-30 15:49:51.018708+0100 Lolo[4786:624058] 0.000000 MB (0.000000) - (null) - (
"public.tiff",
"NeXT TIFF v4.0 pasteboard type",
"dyn.ah62d4rv4gu8zazwuqm10c6xemf1gq54uqm10c6xenv61a3k",
PVPboardInfoPboardType
)
In the second test I opened the image in Preview. I copied the image, got no error. Checking the clipboard (pasteboard) in the Finder says it has an TIFF image, but shows nothing. Printing the contents using pasteboard code, reveals that the pasteboard contains the TIFF type, but no data.
It seems that Mac OS (macOS) is simply not capable to store a image as big as the one used.
Upvotes: 2