Colin Wilson
Colin Wilson

Reputation: 271

Copy multiple NSImage to NSPasteboard

I'm trying to copy multiple NSImages to the Pasteboard using Swift 4 - like this:

private func putItemsOnPasteboard (_ items: [Int]) {
    if let images = mainImageController?.getNSImages(for: items) {
        NSPasteboard.general.clearContents()
        NSPasteboard.general.writeObjects(images)
        if let c = NSPasteboard.general.pasteboardItems?.count {
            print (c)
        }
    }
}

NSImage implements NSPasteboardWriting, and it works fine. The snag is, if I then paste into, say, Mail, it only pastes the first image, and I'm struggling to figure out why.

For instance, if I call the function with three images, it all appears to work, and my diagnostic 'print (c)' correctly shows '3'. But if I paste into Mail (or OneNote etc.) it only paste the first image.

I know Mail supports pasting multiple images, because I can select three thumbnails in Apple Photos, copy them to the pasteboard, and it correctly pastes all three into Mail.

Any clues would be gratefully appreciated!

Upvotes: 1

Views: 1354

Answers (2)

Colin Wilson
Colin Wilson

Reputation: 271

Charles Srstka's answer was very helpful here. It appears that though you can put multiple NSImages on the Pasteboard, you can only paste one.

Swift's URL object doesn't comply with NSPasteboardWriting, but NSURL does, and it doesn't have the restriction of being only able to paste one.

So this worked

    private func putImagesOnPasteboard (_ images: [Image], folderURL: URL) {
    let imageURLs = images.map() {
        image in
        return NSURL (fileURLWithPath: folderURL.appendingPathComponent(image.fileName).path)
    }
    NSPasteboard.general.clearContents()
    NSPasteboard.general.writeObjects(imageURLs)
}

Upvotes: 1

Charles Srstka
Charles Srstka

Reputation: 17050

If I copy a group of photos in Photos, and then inspect the pasteboard types, I get:

import Cocoa

print(NSPasteboard.general.types?.map { $0.rawValue } ?? [])

outputs:

["dyn.ah62d4rv4gu8ywyc2nbu1g7dfqm10c6xekr1067dwr70g23pw", "IPXPasteboardController", "com.apple.PhotoPrintProduct.photoUUID", "public.file-url", "CorePasteboardFlavorType 0x6675726C", "dyn.ah62d4rv4gu8y6y4grf0gn5xbrzw1gydcr7u1e3cytf2gn", "NSFilenamesPboardType", "dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu", "Apple URL pasteboard type"]

Of those types, the one that looks interesting to me is public.file-url, which suggests that Photos is copying a group of URLs onto the pasteboard. Let's test that hypothesis:

import Cocoa

print(NSPasteboard.general.readObjects(forClasses: [NSURL.self], options: nil) ?? [])

outputs:

[file:///Users/*deleted*/Pictures/Photos%20Library.photoslibrary/resources/proxies/derivatives/1e/00/1e03/UNADJUSTEDNONRAW_thumb_1e03.jpg, file:///Users/*deleted*/Pictures/Photos%20Library.photoslibrary/resources/proxies/derivatives/1e/00/1e04/UNADJUSTEDNONRAW_thumb_1e04.jpg, file:///Users/*deleted*/Pictures/Photos%20Library.photoslibrary/resources/proxies/derivatives/1e/00/1e05/kOBCUhzGRcyeVfBCC8VfvQ_thumb_1e05.jpg]

The output is a list of URLs to JPEG files, suggesting that Photos is indeed providing a list of URLs and putting those on the pasteboard. So perhaps you could save the TIFF representations of your NSImages to a temporary location, and then write the URLs to those temporary files onto the pasteboard, and it would work.

Upvotes: 3

Related Questions