Получение данных глубины от 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.
Вот ссылка:
Если вам не хочется его смотреть, ознакомьтесь с этой функцией, которую я написал, которая делает почти то же самое, что и в видео.
Вы должны предоставить функцию [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
, который дает гораздо более высокое разрешение маски только для объекта съемки на портретных изображениях и отлично подходит для создания эффектов в стиле зеленого экрана.