Swift:HEIC 图像的 PHAssetChangeRequest 失败
Swift: PHAssetChangeRequest fails for HEIC image
我想对图库中的图像(由 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,或者在选择图像并单击 'Edit Image' 按钮后,您可以在图像顶部看到全名预习。
注意 2:出于某种原因,当我将 HEIC 图像从 iPhone 发送到 Mac 并将其发送回 iPhone 时,它可以在新的副本,它仍然是 HEIC 并保留原始图像方向。
给你,它是这样工作的:创建一个 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))")
})
})
}
}
我想对图库中的图像(由 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,或者在选择图像并单击 'Edit Image' 按钮后,您可以在图像顶部看到全名预习。
注意 2:出于某种原因,当我将 HEIC 图像从 iPhone 发送到 Mac 并将其发送回 iPhone 时,它可以在新的副本,它仍然是 HEIC 并保留原始图像方向。
给你,它是这样工作的:创建一个 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))")
})
})
}
}