将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?
Posted
技术标签:
【中文标题】将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?【英文标题】:Convert UIImage to NSData and convert back to UIImage in Swift? 【发布时间】:2015-11-24 16:31:38 【问题描述】:我正在尝试将UIImage
保存到NSData
,然后在Swift 中将NSData
读回新的UIImage
。要将UIImage
转换为NSData
,我使用以下代码:
let imageData: NSData = UIImagePNGRepresentation(myImage)
如何将imageData
(即NSData
)转换回新的UIImage
?
【问题讨论】:
【参考方案1】:UIImage(data:imageData,scale:1.0)
假设图像的比例为 1。
在 swift 4.2 中,使用以下代码获取数据()。
image.pngData()
【讨论】:
【参考方案2】:使用imageWithData:
方法,该方法被转换为UIImage(data:)
Swift
let image : UIImage = UIImage(data: imageData)
【讨论】:
【参考方案3】:谢谢。帮了我很多。转换为 Swift 3 并正常工作
要保存:let data = UIImagePNGRepresentation(image)
要加载:let image = UIImage(data: data)
【讨论】:
let imagePt = UIImage(data: caminhodaImagem)
还不够吗?【参考方案4】:
保存为数据:
从 StoryBoard 中,如果您想在 MainStoryBoard 的 imageView 上保存“图像”数据,以下代码将起作用。
let image = UIImagePNGRepresentation(imageView.image!) as NSData?
将“图像”加载到 imageView: 看感叹号“!”,“?”密切关注这是否与此相同。
imageView.image = UIImage(data: image as! Data)
“NSData”类型在此过程中自动转换为“Data”类型。
【讨论】:
这在我尝试时返回 nil 值?和建议? 澄清一下,我已将 excel 文件保存为 pdf,我知道我的功能可以正常工作,因为我可以将所述 PDF 附加到电子邮件并在我的手机“pdf 查看器”中查看应用程序。 PDF 存储为 NSData。如果我打印(我的 data.thePDF)我得到一个值,但是在使用上面的脚本转换它之后它返回 nil。我还尝试将 NSData 转换为数据,这将打印一个值,但是当我将数据覆盖到 UIImage 时,它返回 nil。 :(【参考方案5】:为了代码的安全执行,使用 if-let
块和 Data
来防止应用程序崩溃 & ,因为函数 UIImagePNGRepresentation
返回一个可选值。
if let img = UIImage(named: "TestImage.png")
if let data:Data = UIImagePNGRepresentation(img)
// Handle operations with data here...
注意:Data 是 Swift 3+ 类。使用 Data 而不是 NSData 斯威夫特 3+
通用图像操作(如 png 和 jpg 两者):
if let img = UIImage(named: "TestImage.png") //UIImage(named: "TestImage.jpg")
if let data:Data = UIImagePNGRepresentation(img)
handleOperationWithData(data: data)
else if let data:Data = UIImageJPEGRepresentation(img, 1.0)
handleOperationWithData(data: data)
*******
func handleOperationWithData(data: Data)
// Handle operations with data here...
if let image = UIImage(data: data)
// Use image...
通过使用扩展:
extension UIImage
var pngRepresentationData: Data?
return UIImagePNGRepresentation(self)
var jpegRepresentationData: Data?
return UIImageJPEGRepresentation(self, 1.0)
*******
if let img = UIImage(named: "TestImage.png") //UIImage(named: "TestImage.jpg")
if let data = img.pngRepresentationData
handleOperationWithData(data: data)
else if let data = img.jpegRepresentationData
handleOperationWithData(data: data)
*******
func handleOperationWithData(data: Data)
// Handle operations with data here...
if let image = UIImage(data: data)
// Use image...
【讨论】:
【参考方案6】:现在在 Swift 4.2 中,您可以使用 pngData()
的 UIImage
的新实例方法从图像中获取数据
let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()
【讨论】:
Swift 4.2 是 Beta 版吗?我没有看到此功能可用 好像改名了 'pngData()' 已重命名为 'UIImagePNGRepresentation(_:)'【参考方案7】:图像到数据:-
if let img = UIImage(named: "xxx.png")
let pngdata = img.pngData()
if let img = UIImage(named: "xxx.jpeg")
let jpegdata = img.jpegData(compressionQuality: 1)
数据到图像:-
guard let image = UIImage(data: pngData) else return
【讨论】:
【参考方案8】:详情
Xcode 10.2.1 (10E1001)、Swift 5解决方案 1
guard let image = UIImage(named: "img") else return
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()
解决方案 2.1
extension UIImage
func toData (options: NSDictionary, type: CFString) -> Data?
guard let cgImage = cgImage else return nil
return autoreleasepool () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else return nil
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
解决方案2.1的使用
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
let options: NSDictionary = [
kCGImagePropertyOrientation: 6,
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: 0.5
]
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
guard let data = image.toData(options: options, type: kUTTypeJPEG) else return
let size = CGFloat(data.count)/1000.0/1024.0
print("\(size) mb")
解决方案 2.2
extension UIImage
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data?
guard cgImage != nil else return nil
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
func toData (options: NSDictionary, type: ImageType) -> Data?
guard cgImage != nil else return nil
return toData(options: options, type: type.value)
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data?
guard let cgImage = cgImage else return nil
return autoreleasepool () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else return nil
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString
switch self
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
解决方案2.2的使用
let compressionQuality: CGFloat = 0.4
guard let data = image.toJpegData(compressionQuality: compressionQuality) else return
printSize(of: data)
let options: NSDictionary = [
kCGImagePropertyHasAlpha: true,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
guard let data2 = image.toData(options: options, type: .png) else return
printSize(of: data2)
问题
图像表示会占用大量的cpu和内存资源。因此,在这种情况下,最好遵循几条规则:
- 不要在主队列上运行 jpegData(compressionQuality:)
- 只同时运行一个 jpegData(compressionQuality:)
错误:
for i in 0...50
DispatchQueue.global(qos: .utility).async
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
对:
let serialQueue = DispatchQueue(label: "queue", qos: .utility, attributes: [], autoreleaseFrequency: .workItem, target: nil)
for i in 0...50
serialQueue.async
let quality = 0.02 * CGFloat(i)
//let data = image.toJpegData(compressionQuality: quality)
let data = image.jpegData(compressionQuality: quality)
let size = CGFloat(data!.count)/1000.0/1024.0
print("\(i), quality: \(quality), \(size.rounded()) mb")
链接
UTI Image Content Types CGImageDestinationAddImage(::_:) Thinking about Memory: Converting UIImage to Data in Swift Different resize technics【讨论】:
Vasily,这非常有帮助。我可以使用您的代码将 UIImages 转换为 bmps。我还需要从 bmp 中删除 alpha。我试图设置选项来删除 alpha 并且似乎无法让它摆脱图层。我这样调用: let options: NSDictionary = [kCGImagePropertyHasAlpha: false] let convertToBmp = image.toData(options: options, type: .bmp) @Gallaugher 你确定它不起作用吗?尝试创建没有 alpha 的 png 图像并检查它。可能无法将 kCGImagePropertyHasAlpha 属性与 bmp 一起使用。 @vasily-bodnarchuk 感谢领导(以及更早的代码)。我摆脱了 alpha - 我无法通过 png 完成它,但我使用了 resizedImage.toJpegData,alpha 为 false,然后将此数据转换回 UIImage,然后执行 .bmp 类型的 toData。选项没有影响,但这在 Photoshop 中删除了 Alpha 层并创建了一个较小的文件。仍然无法生成 PyPortal 所需的精确 16 位光栅图形 bmp 格式。由于某种原因,当我通过在线转换之类的工具进行转换时,转换的数据没有显示出来。谢谢。 @vasily-bodnarchuk,我使用您的有用代码保存的 bmp 在 Photoshop 中打开,带有 bmp 选项“翻转行顺序”。如果我在“另存为...”之后出现的“BMP 选项”屏幕上重新保存并取消选中此选项,然后在 PyPortal 上加载 bmp,更新后的 bmp 显示。我没有看到任何看起来像“翻转行顺序”选项的 Apple 文档,我不确定为什么这会显示为默认保存并且我不确定如何在 Swift 中“撤消”它。顺便说一句:我已将我的 Q 和相关文件发布在:***.com/questions/57241391/… 谢谢!【参考方案9】:斯威夫特 5
让你创建为 UIImage 的图像成为图像
image.pngData() as NSData?
【讨论】:
请花点时间阅读help center 中的editing help。 Stack Overflow 上的格式与其他网站不同。【参考方案10】:将此用于简单的解决方案
static var UserProfilePhoto = UIImage()
guard let image = UIImage(named: "Photo") else return
guard let pngdata = image.pngData() else return
UserProfilePhoto = UIImage(data: pngdata)!
【讨论】:
以上是关于将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UIImage 转换为 NSData 或 CFDataRef?