Получение данных глубины от UIImagePickerController

Я пытаюсь получить данные о глубине, связанные с изображением в PhotoLibrary. Я могу получить изображение и URL, но я не могу получить дополнительные данные, связанные с ним. Призыв к CGImageSourceCreateWithURL возвращает источник, но вызов CGImageSourceCopyAuxiliaryDataInfoAtIndex возвращается nil для обоих kCGImageAuxiliaryDataTypeDisparity а также kCGImageAuxiliaryDataTypeDepth, Есть что-то, чего я здесь не хватает?

func imagePickerController(_ picker: UIImagePickerController,    didFinishPickingMediaWithInfo info: [String : Any]) {
    let image = info[UIImagePickerControllerOriginalImage]
    let url = info[UIImagePickerControllerImageURL]
    print("url=",url)

    guard let source = CGImageSourceCreateWithURL(url as! CFURL, nil) else {
        return
    }
    guard let auxDataInfo = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDisparity) as? [AnyHashable : Any] else {
        return
    }
}

1 ответ

Я боролась с этим целый день! Я наконец понял это, посмотрев первую половину видео WWDC под названием "Редактирование изображений с глубиной".

Моя проблема заключалась в использовании URL-адреса для изображения, не принадлежащего PHAsset.

Вот ссылка:

ССЫЛКА НА ВИДЕО WWDC

Если вам не хочется его смотреть, ознакомьтесь с этой функцией, которую я написал, которая делает почти то же самое, что и в видео.

Вы должны предоставить функцию [info], которая возвращается функцией DID_FINISH_PICKING_IMAGE_WITH_INFO из UIImagePickerDelegate.

Перед использованием этой функции - обратите внимание, что на самом деле она не работает! Однако на это приятно смотреть, потому что здесь четко показаны шаги. Но из-за асинхронного поведения функция всегда будет возвращать nil, прежде чем у нее будет возможность установить локальную переменную глубины в AVDepthData.

Мое решение состояло в том, чтобы разбить эту функцию на части и использовать Grand Central Dispatch для создания группы отправки, ввести ее, получить imageURL из PHAsset и затем покинуть группу отправки. После выхода из группы отправки функция DispatchGroup.NOTIFIED продолжила остальную часть процесса.

Надеюсь, это поможет!!!

     func returndepthdata(usingimageinfo: [UIImagePickerController.InfoKey : Any]) -> AVDepthData? {
          var depthdata: AVDepthData! = nil

          if let photoasset = usingimageinfo[.phAsset] as? PHAsset {
               let input = photoasset.requestContentEditingInput(with: nil, completionHandler: { (input, info) in
                    if let imageurl = input?.fullSizeImageURL {
                         if let source = CGImageSourceCreateWithURL(imageurl as CFURL, nil) {
                              if let imageproperties = CGImageSourceCopyProperties(source, nil) {
                                   if let disparityinfo = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDisparity) {
                                        if let truedepthdata = try? AVDepthData(fromDictionaryRepresentation: disparityinfo as! [AnyHashable : Any]) {
                                             depthdata = truedepthdata
                                        }
                                   }
                              }
                         }
                    }
               })
          }
          return depthdata
     }

URL изображения предоставлен UIImagePickerController не включает какие-либо метаданные, связанные с глубиной. Чтобы получить эту информацию, вы должны получить доступ к PHAsset используя API PhotoBook.

Сначала импортируйте API:

import Photos

Перед отображением средства выбора изображений запросите доступ пользователя к фотокниге. Вам нужно будет добавить ключ информационного словаря для использования библиотеки фотографий, чтобы это работало:

    switch PHPhotoLibrary.authorizationStatus() {
    case .notDetermined:
        PHPhotoLibrary.requestAuthorization { (status) in
            if status == .authorized {
                DispatchQueue.main.async {
                    // Display image picker here
                }
            }
        }
    case .authorized: // Display image picker here
    case .denied, .restricted: // Display appropriate error here
    }

Теперь в вашем делегате выбора изображений вы можете сделать это:

    if let asset = info[.phAsset] as? PHAsset {
        PHImageManager.default().requestImageData(for: asset, options: nil) { (imageData, dataType, orientation, info) in
            let url = info?["PHImageFileURLKey"] as? URL
            // Pass this URL to your existing code.
        }
    }

Обратите внимание, что файл может содержать информацию о глубине или несоответствии. Вы можете конвертировать между ними достаточно легко, но вам может понадобиться проверить, какой из них вы используете CGImageSourceCopyProperties(), Также обратите внимание на новые дополнительные данные о глубине, kCGImageAuxiliaryDataTypePortraitEffectsMatte, который дает гораздо более высокое разрешение маски только для объекта съемки на портретных изображениях и отлично подходит для создания эффектов в стиле зеленого экрана.

Другие вопросы по тегам