pow-il
pow-il

Reputation: 73

How to paste an NSImage correctly from NSPasteboard?

Ok, Here's the code I'm using :

if let image = NSImage(pasteboard: pasteboard){
    //..
}

And I have 3 ways where images come into the app:

  1. If the image is dragged to the window, and using the dragging pasteboard, the image is correct.
  2. If the image is copied in browser, "Copy Image".. and using NSPasteboard.general().. The image is pasted correctly.
  3. If the image is copied in Finder, right click -> Copy "image-name.jpg". then the pasted image is NOT correct. Instead I get the icon for JPEG file type.

I tried other methods, including apple's snippet (same result, I get icon instead of the image itself) :

NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSImage class]];
NSDictionary *options = [NSDictionary dictionary];

BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
if (ok) {
    NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
    NSImage *image = [objectsToPaste objectAtIndex:0];
    [imageView setImage:image];
}

Upvotes: 5

Views: 2130

Answers (2)

Code Different
Code Different

Reputation: 93191

The pasteboard does contain a path to the file, which you can use it to load the image from disk:

func paste(_ sender: AnyObject) {
    let pasteboard = NSPasteboard.general()

    if let data = pasteboard.data(forType: kUTTypeFileURL),
        let str =  String(data: data, encoding: .utf8),
        let url = URL(string: str),
        let image = NSImage(contentsOf: url)
    {
        imageView.image = image
    }
}

Upvotes: 9

Ken Thomases
Ken Thomases

Reputation: 90681

That's because the Finder isn't copying an image, it's copying a file item. The primary representation of this is a URL, but another representation is the file icon. None of the representations are the content of the file (i.e. the JPEG image).

You could first check if the pasteboard can provide a URL and create the image from the URL. Only if that fails try creating an image directly from the pasteboard.

Alternatively, you could enumerate the pasteboardItems, which would give you them in the order that the source app thinks is most relevant. Stop at the first which is either a URL to an image file or image data.

Upvotes: 3

Related Questions