Как правильно вставить NSImage из NSPasteboard?

Хорошо, вот код, который я использую:

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

И у меня есть 3 способа, как изображения попадают в приложение:

  1. Если изображение перетаскивается в окно и используется монтажный стол перетаскивания, изображение правильное.
  2. Если изображение копируется в браузере, «Копировать изображение».. и с помощью NSPasteboard.general().. Изображение вставляется правильно.
  3. Если изображение копируется в Finder, щелкните правой кнопкой мыши -> Копировать "image-name.jpg". тогда вставленное изображение НЕ является правильным. Вместо этого я получаю значок для типа файла JPEG.

Я пробовал другие методы, в том числе фрагмент яблока (тот же результат, я получаю значок вместо самого изображения):

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];
}

person pow-il    schedule 19.02.2017    source источник


Ответы (2)


Монтажный стол содержит путь к файлу, который вы можете использовать для загрузки изображения с диска:

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
    }
}
person Code Different    schedule 19.02.2017
comment
Да, это работает отлично. Есть идеи, есть ли где-нибудь официальное определение для public.file-url? Кажется, что в документации отсутствуют такие детали того, как на самом деле работает монтажный стол. - person pow-il; 19.02.2017
comment
На самом деле для этого есть константа: kUTTypeFileURL (документация) Я получил это значение, изучив элементы монтажного стола в отладчике - person Code Different; 19.02.2017
comment
Ваша реализация немного окольная: пусть filenameURL = NSURL(from: pasteboard) как URL? экономит на промежуточных этапах. (Увы, получить URL-адрес напрямую с монтажного стола невозможно.) - person green_knight; 26.02.2019

Это потому, что Finder копирует не изображение, а элемент файла. Основным представлением этого является URL-адрес, но другим представлением является значок файла. Ни одно из представлений не является содержимым файла (т. е. изображения JPEG).

Сначала вы можете проверить, может ли монтажный стол предоставить URL-адрес, и создать изображение из URL-адреса. Только если это не поможет, попробуйте создать образ прямо из монтажного стола.

В качестве альтернативы вы можете перечислить pasteboardItems, что даст вам их в порядке, который исходное приложение считает наиболее подходящим. Остановитесь на первом, который является либо URL-адресом файла изображения, либо данными изображения.

person Ken Thomases    schedule 19.02.2017
comment
Спасибо за объяснение. Это было очень полезно - person pow-il; 19.02.2017