将 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并返回UIImage

UIImage 神秘地转换为 NSData

如何将 UIImage 转换为 NSData 或 CFDataRef?

将 NSData 数组转换为 UIImage 数组

将 UIImage 转换为 NSData 并与核心数据一起保存

将UIImage转换为数据URI