Objective c NSPasteBoard_setData:PNG文件的forType NSImage失败

Objective c NSPasteBoard_setData:PNG文件的forType NSImage失败,objective-c,macos,png,Objective C,Macos,Png,我正在使用将图像文件复制到剪贴板。这是完整的源代码 #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 NSIma

我正在使用将图像文件复制到剪贴板。这是完整的源代码

#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);
}
从bash管道复制PNG图像也会失败

$ 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.
使用它测试另一个随机PNG屏幕截图效果很好。我注意到上面的错误消息是
Type:public.tiff
。PNG最初是使用ImageMagic从SVG转换而来的

代码有什么问题,还是PNG格式不正确


我做了一些测试,结果非常显著

第一次测试:

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]];
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]);
输出:

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.
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
)
我可以将图像作为PNG数据写入粘贴板。NSImage对象不能像您的情况那样写入。NSImage对象以多种格式存储自己,包括TIFF数据,因此为了测试,我打印了它将写入粘贴板的图像数据的大小。它是347.824566MB,所以可能有点太大了

第二次测试:

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]];
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]);
输出:

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.
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
)
在第二次测试中,我在预览中打开了图像。我复制了图像,没有错误。检查Finder中的剪贴板(粘贴板)时,它会显示TIFF图像,但不会显示任何内容。使用粘贴板代码打印内容会显示粘贴板包含TIFF类型,但没有数据

似乎Mac OS(macOS)根本无法存储与所用图像一样大的图像