Swift:HEIC 图像的 PHAssetChangeRequest 失败

Posted

技术标签:

【中文标题】Swift:HEIC 图像的 PHAssetChangeRequest 失败【英文标题】:Swift: PHAssetChangeRequest fails for HEIC image 【发布时间】:2019-07-29 20:24:09 【问题描述】:

我想对图库中的图像(由 iPhone 相机拍摄)执行编辑,例如 JEPG 压缩,但是当输入图像是 HEIC 图像,但适用于 JPEG 图像。

我通过UIImagePickerController 方法在PHAsset 对象中检索图像:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) 
        if let asset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset 
            self.asset = asset
        

        //...
     

这个函数编辑选中的图像:

func editImage() 
if let _asset = self.asset 
        _asset.requestContentEditingInput(with: nil, completionHandler:  (contentEditingInput, info) in
            let fullURL: URL?
            fullURL = contentEditingInput!.fullSizeImageURL

            let output = PHContentEditingOutput(contentEditingInput:
                contentEditingInput!)
            let archivedData = try? NSKeyedArchiver.archivedData(withRootObject: "HEICEditor", requiringSecureCoding: false)
            let adjustmentData =
                PHAdjustmentData(formatIdentifier:
                    "HEICEditor.App",
                                 formatVersion: "1.0",
                                 data: archivedData!)

            output.adjustmentData = adjustmentData
            let imageData = UIImage.init(contentsOfFile: fullURL!.path)?.jpegData(compressionQuality: 0.5)

            do 
                try imageData!.write(to: output.renderedContentURL, options: .atomic)
             catch let error 
                print("error writing data:\(error)")
            

            phphotoLibrary.shared().performChanges(
                let request = PHAssetChangeRequest(for: _asset)
                request.contentEditingOutput = output

            , completionHandler:  (result, error) in
               print("error writing data:\(error)")

            )

        )

    

带有示例HEIC 图像的项目可在https://github.com/maysamsh/Swift-Playground-EditHEIC 获得

注意 1:使用 EXIF 查看器,您可以查看图像是否为 HEIC,或者在选择图像并单击“编辑图像”按钮后,您可以在图像预览顶部看到全名。

注意 2:由于某种原因,当我将 HEIC 图像从 iPhone 发送到 Mac 并将其发送回 iPhone 时,它​​可以在新副本上工作,该副本仍然是 HEIC 并保留原始图像方向。

【问题讨论】:

【参考方案1】:

给你,它是这样工作的:创建一个CGImageDestination,将输出写入.renderedContentURL,执行the PHAssetChangeRequest()

func editImage() 
    if let _asset = self.asset 
        let options = PHContentEditingInputRequestOptions()
        options.canHandleAdjustmentData = (adjustmeta: PHAdjustmentData)
            -> Bool in
            return true
        
        _asset.requestContentEditingInput(with: options, completionHandler:  (contentEditingInput, info) in
            let fullURL: URL?
            fullURL = contentEditingInput!.fullSizeImageURL
            let output = PHContentEditingOutput(contentEditingInput:
                contentEditingInput!)
            let archivedData = try? NSKeyedArchiver.archivedData(withRootObject: "HEICEditor", requiringSecureCoding: false)
            let adjustmentData =
                PHAdjustmentData(formatIdentifier:
                    "HEICEditor.App",
                                 formatVersion: "1.0",
                                 data: archivedData!)


            let orientation = contentEditingInput?.fullSizeImageOrientation
            let outputURL = output.renderedContentURL
            let cgImage = 
                () -> CGImage in
                let image = UIImage.init(contentsOfFile: fullURL!.path)!
                let imageData = image.jpegData(compressionQuality: 1)
                let ciImage = CIImage(data: imageData!)!.oriented(forExifOrientation: orientation!)

                return CIContext(options: nil).createCGImage(ciImage, from: ciImage.extent)!
            ()

            let cgImageDestination = CGImageDestinationCreateWithURL(outputURL as CFURL, kUTTypeJPEG, 1, nil)!
            CGImageDestinationAddImage(cgImageDestination, cgImage, [
                kCGImageDestinationLossyCompressionQuality as String:0.7
                ] as CFDictionary)
            CGImageDestinationFinalize(cgImageDestination)


            output.adjustmentData = adjustmentData
            self.infoLabel.text = "fullSizeImageURL: \(fullURL?.lastPathComponent ?? "N/A")\n" +
            "renderedContentURL: \(output.renderedContentURL.lastPathComponent)"

            PHPhotoLibrary.shared().performChanges(
                let request = PHAssetChangeRequest(for: _asset)
                request.contentEditingOutput = output
            , completionHandler:  (result, error) in
                print("result: \(result), error: \(String(describing: error))")
            )

        )

    

【讨论】:

kUTTypeJPEG 在哪里?我收到:在范围内找不到“kUTTypeJPEG”。如何导入? 可能需要导入Photos 在文件顶部添加import Photos 不,我使用“public.jpeg”作为字符串解决了。

以上是关于Swift:HEIC 图像的 PHAssetChangeRequest 失败的主要内容,如果未能解决你的问题,请参考以下文章

检测 iOS 图像数据是 HEIF 还是 HEIC

将 HEIC 格式图像文件转换成 JPEG,BMP 格式

将 heic 转换为 JPG 并获取文件位置

将使用 UIImagePickerController 拍摄的图像以 HEIC 格式保存到照片卷

Heic图片格式怎么查看 如何打开heic文件

HEIC格式是什么?怎么将HEIC图片转换JPG?