0

PHPickerViewController を使用して画像と動画を選択しています。私のアプリはファイルを保存し、iOS 以外のアプリケーションで使用するため、ライブフォトの使用には興味がありません。現時点では、次の 2 つのチュートリアルを組み合わせた livePhoto から画像を抽出するために次の方法を使用しています。

https://www.appcoda.com/phpicker/

https://www.limit-point.com/blog/2018/live-photos/

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    if results != nil {
        for result in results! {
            let itemProvider = result.itemProvider

            guard let typeIdentifier = itemProvider.registeredTypeIdentifiers.first,
                  let utType = UTType(typeIdentifier)
            else { continue }

            if utType.conforms(to: .image) {
                self.getPhoto(from: itemProvider, isLivePhoto: false)
            } else if utType.conforms(to: .movie) {
                self.getVideo(from: itemProvider, typeIdentifier: typeIdentifier)
            } else {
                self.getPhoto(from: itemProvider, isLivePhoto: true)
            }
        }
    }
}

private func getPhoto(from itemProvider: NSItemProvider, isLivePhoto: Bool) {
    let objectType: NSItemProviderReading.Type = !isLivePhoto ? UIImage.self : PHLivePhoto.self
    if itemProvider.canLoadObject(ofClass: objectType) {
        itemProvider.loadObject(ofClass: objectType) { object, error in
            if let error = error {
                print(error.localizedDescription)
            }
 
            if !isLivePhoto {
                if let image = object as? UIImage {
                    DispatchQueue.main.async {
                        // use image
                    }
                }
            } else {
                if let livePhoto = object as? PHLivePhoto {
                    DispatchQueue.main.async {
                        let livePhotoResources = PHAssetResource.assetResources(for: livePhoto)
                        for resource in livePhotoResources {
                            if resource.type == .photo {
                                let buffer = NSMutableData()
                                var dataRequestID:PHAssetResourceDataRequestID = PHInvalidAssetResourceDataRequestID
                                
                                let options = PHAssetResourceRequestOptions()
                                options.isNetworkAccessAllowed = true
                                
                                dataRequestID = PHAssetResourceManager.default().requestData(for: resource, options: options, dataReceivedHandler: { (data:Data) in
                                    buffer.append(data)
                                    
                                }, completionHandler: { (error:Error?) in
                                    // buffer now contains the resource data
                                    if let image = UIImage(data: buffer as Data) {
                                        // use image
                                    }
                                })
                                
                            } 
                        }
                    }
                }
            }
            
        }
    }
}

このアプローチはうまくいくようで、写真と livePhoto の両方の UIImage を取得できます。

これについてもっと簡単な方法があるかどうか疑問に思っていますか?PHPickerViewController のプレビューは単なる画像なので、livePhoto の画像リソースを直接抽出できますか?

また、ピッカーは次のように定義されています。

var config = PHPickerConfiguration()
config.filter = .any(of: [.images, .videos, .livePhotos])
config.selectionLimit = 10
config.preferredAssetRepresentationMode = .current

let controller = PHPickerViewController(configuration: config)

livePhotos なしでフィルターを定義するだけで、livePhotos が表示され、uiType.conforms(to: .image) が livePhotos に対して true を返すようになることを期待していましたが、そうではありませんでした。

4

0 に答える 0