如何在 Swift 中将 UIImage 转换为 HEIF / HEIC 数据?
How can I convert from UIImage to HEIF / HEIC Data in Swift?
NSKeyedArchiver
是否适合将UIImage
转换为Data
?
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: UIImage(named: somePath), requiringSecureCoding: true)
...
} catch {
print(error)
}
或者是矫枉过正,使用pngData()
更合适?
let image = UIImage(named: somePath)
let data = image?.pngData()
以及如何从 UIImage
转换为 HEIF / HEIC Data
?
目标是将图像保存到设备的文件系统。
没有。切勿使用 NSKeyedArchiver 将图像转换为数据。选择一种图像格式(HEIC、PNG、JPEG 等)并获取其数据表示形式。在保存要在 UI 中使用的图像时,您应该只使用 PNG。大多数时候 jpeg 是首选。如果设备支持 HEIC,考虑到图像质量和减少的数据大小,它是一个选项。
如果您需要检查用户设备是否支持 HEIC 类型,您可以按以下方式进行:
var isHeicSupported: Bool {
(CGImageDestinationCopyTypeIdentifiers() as! [String]).contains("public.heic")
}
如果您需要将图像转换为 HEIC,您需要从 UIImage
获取 CGImage
并将 UIImage
的 imageOrientation
转换为 CGImagePropertyOrientation
在创建其数据表示时保留方向:
extension UIImage {
var heic: Data? { heic() }
func heic(compressionQuality: CGFloat = 1) -> Data? {
guard
let mutableData = CFDataCreateMutable(nil, 0),
let destination = CGImageDestinationCreateWithData(mutableData, "public.heic" as CFString, 1, nil),
let cgImage = cgImage
else { return nil }
CGImageDestinationAddImage(destination, cgImage, [kCGImageDestinationLossyCompressionQuality: compressionQuality, kCGImagePropertyOrientation: cgImageOrientation.rawValue] as CFDictionary)
guard CGImageDestinationFinalize(destination) else { return nil }
return mutableData as Data
}
}
extension CGImagePropertyOrientation {
init(_ uiOrientation: UIImage.Orientation) {
switch uiOrientation {
case .up: self = .up
case .upMirrored: self = .upMirrored
case .down: self = .down
case .downMirrored: self = .downMirrored
case .left: self = .left
case .leftMirrored: self = .leftMirrored
case .right: self = .right
case .rightMirrored: self = .rightMirrored
@unknown default:
fatalError()
}
}
}
extension UIImage {
var cgImageOrientation: CGImagePropertyOrientation { .init(imageOrientation) }
}
无损压缩的用法:
if isHeicSupported, let heicData = image.heic {
// write your heic image data to disk
}
或对您的图片进行压缩:
if isHeicSupported, let heicData = image.heic(compressionQuality: 0.75) {
// write your compressed heic image data to disk
}
NSKeyedArchiver
是否适合将UIImage
转换为Data
?
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: UIImage(named: somePath), requiringSecureCoding: true)
...
} catch {
print(error)
}
或者是矫枉过正,使用pngData()
更合适?
let image = UIImage(named: somePath)
let data = image?.pngData()
以及如何从 UIImage
转换为 HEIF / HEIC Data
?
目标是将图像保存到设备的文件系统。
没有。切勿使用 NSKeyedArchiver 将图像转换为数据。选择一种图像格式(HEIC、PNG、JPEG 等)并获取其数据表示形式。在保存要在 UI 中使用的图像时,您应该只使用 PNG。大多数时候 jpeg 是首选。如果设备支持 HEIC,考虑到图像质量和减少的数据大小,它是一个选项。
如果您需要检查用户设备是否支持 HEIC 类型,您可以按以下方式进行:
var isHeicSupported: Bool {
(CGImageDestinationCopyTypeIdentifiers() as! [String]).contains("public.heic")
}
如果您需要将图像转换为 HEIC,您需要从 UIImage
获取 CGImage
并将 UIImage
的 imageOrientation
转换为 CGImagePropertyOrientation
在创建其数据表示时保留方向:
extension UIImage {
var heic: Data? { heic() }
func heic(compressionQuality: CGFloat = 1) -> Data? {
guard
let mutableData = CFDataCreateMutable(nil, 0),
let destination = CGImageDestinationCreateWithData(mutableData, "public.heic" as CFString, 1, nil),
let cgImage = cgImage
else { return nil }
CGImageDestinationAddImage(destination, cgImage, [kCGImageDestinationLossyCompressionQuality: compressionQuality, kCGImagePropertyOrientation: cgImageOrientation.rawValue] as CFDictionary)
guard CGImageDestinationFinalize(destination) else { return nil }
return mutableData as Data
}
}
extension CGImagePropertyOrientation {
init(_ uiOrientation: UIImage.Orientation) {
switch uiOrientation {
case .up: self = .up
case .upMirrored: self = .upMirrored
case .down: self = .down
case .downMirrored: self = .downMirrored
case .left: self = .left
case .leftMirrored: self = .leftMirrored
case .right: self = .right
case .rightMirrored: self = .rightMirrored
@unknown default:
fatalError()
}
}
}
extension UIImage {
var cgImageOrientation: CGImagePropertyOrientation { .init(imageOrientation) }
}
无损压缩的用法:
if isHeicSupported, let heicData = image.heic {
// write your heic image data to disk
}
或对您的图片进行压缩:
if isHeicSupported, let heicData = image.heic(compressionQuality: 0.75) {
// write your compressed heic image data to disk
}