ios 将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32297704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:27:09  来源:igfitidea点击:

Convert UIImage to NSData and convert back to UIImage in Swift?

iosswiftuiimagepngnsdata

提问by pete

I'm trying to save a UIImageto NSDataand then read the NSDataback to a new UIImagein Swift. To convert the UIImageto NSDataI'm using the following code:

我正在尝试保存一个UIImagetoNSData然后在 Swift 中读NSData回一个新UIImage的。要转换UIImageNSData我使用以下代码:

let imageData: NSData = UIImagePNGRepresentation(myImage)

How do I convert imageData(i.e., NSData) back to a new UIImage?

如何将imageData(即NSData)转换回新的UIImage

回答by algal

UIImage(data:imageData,scale:1.0)presuming the image's scale is 1.

UIImage(data:imageData,scale:1.0)假设图像的比例为 1。

In swift 4.2, use below code for get Data().

在 swift 4.2 中,使用下面的代码获取数据()。

image.pngData()

回答by Ivan Sinigaglia

Thanks. Helped me a lot. Converted to Swift 3 and worked

谢谢。帮了我很多。转换为 Swift 3 并开始工作

To save: let data = UIImagePNGRepresentation(image)

保存: let data = UIImagePNGRepresentation(image)

To load: let image = UIImage(data: data)

装载: let image = UIImage(data: data)

回答by dasblinkenlight

Use imageWithData:method, which gets translated to Swift as UIImage(data:)

使用imageWithData:方法,它被翻译成 Swift 作为UIImage(data:)

let image : UIImage = UIImage(data: imageData)

回答by Sh_Khan

Now in Swift 4.2you can use pngData()new instance method of UIImageto get the data from the image

现在在Swift 4.2 中,您可以使用pngData()新的实例方法UIImage从图像中获取数据

let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()

回答by Vasily Bodnarchuk

Details

细节

  • Xcode 10.2.1 (10E1001), Swift 5
  • Xcode 10.2.1 (10E1001),Swift 5

Solution 1

解决方案1

guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()


Solution 2.1

解决方案 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
        }
    }
}

Usage of solution 2.1

解决方案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")


Solution 2.2

解决方案 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
            }
        }
    }
}

Usage of solution 2.2

解决方案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)


Problems

问题

Image representing will take a lot of cpu and memory resources. So, in this case it is better to follow several rules:

图像表示会占用大量的 CPU 和内存资源。因此,在这种情况下,最好遵循以下几条规则:

- do not run jpegData(compressionQuality:) on main queue

- 不要在主队列上运行 jpegData(compressionQuality:)

- run only one jpegData(compressionQuality:) simultaneously

- 同时只运行一个 jpegData(compressionQuality:)

Wrong:

错误的:

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")
    }
}

Right:

对:

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")
    }
}

Links

链接

回答by zemunkh

To save as data:

保存为数据:

From StoryBoard, if you want to save "image" data on the imageView of MainStoryBoard, following codes will work.

从 StoryBoard 中,如果您想在 MainStoryBoard 的 imageView 上保存“图像”数据,以下代码将起作用。

let image = UIImagePNGRepresentation(imageView.image!) as NSData?

To load "image" to imageView: Look at exclamation point "!", "?" closely whether that is quite same as this one.

将“图像”加载到 imageView:查看感叹号“!”、“?” 是否与此完全相同。

imageView.image = UIImage(data: image as! Data)

"NSData" type is converted into "Data" type automatically during this process.

在此过程中,“NSData”类型会自动转换为“Data”类型。

回答by Krunal

For safe execution of code, use if-letblock with Datato prevent app crash & , as function UIImagePNGRepresentationreturns an optional value.

为了安全执行代码,请使用if-letblock withData来防止应用程序崩溃 & ,因为函数UIImagePNGRepresentation返回一个可选值。

if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

Note: Datais Swift 3+ class. Use Data instead of NSData with Swift 3+

注意:数据是 Swift 3+ 类。在 Swift 3+ 中使用 Data 而不是 NSData

Generic image operations (like png & jpg both):

通用图像操作(如 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...
     }
}

By using extension:

通过使用扩展:

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...
     }
}

回答by Yogendra Singh

Image to Data:-

图像到数据:-

    if let img = UIImage(named: "xxx.png") {
        let pngdata = img.pngData()
    }

   if let img = UIImage(named: "xxx.jpeg") {
        let jpegdata = img.jpegData(compressionQuality: 1)
    }

Data to Image:-

数据到图像:-

 let image = UIImage(data: pngData)

回答by dakrawat

Swift 5

斯威夫特 5

let the image you create as UIImage be image

让您创建为 UIImage 的图像成为图像

image.pngData() as NSData?