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

I am trying to save UIImage to NSData and then read NSData back to the new UIImage in Swift. To convert UIImage to NSData I use the following code:

 let imageData: NSData = UIImagePNGRepresentation(myImage) 

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

+121
ios swift png uiimage nsdata
Aug 30 '15 at 14:40
source share
9 answers

UIImage(data:imageData,scale:1.0) assuming the image scale is 1.

In swift 4.2, use the code below to get the data ().

 image.pngData() 
+121
Aug 30 '15 at 14:43
source share

Thank you It helped me a lot. Converted to Swift 3 and worked

To save: let data = UIImagePNGRepresentation(image)

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

+57
Dec 01 '16 at 10:53 on
source share

Use the imageWithData: method, which translates to Swift as UIImage(data:)

 let image : UIImage = UIImage(data: imageData) 
+30
Aug 30 '15 at 14:44
source share

Now in Swift 4.2 you can use pngData() new UIImage instance UIImage to get data from an image

 let profileImage = UIImage(named:"profile")! let imageData = profileImage.pngData() 
+15
Jun 06 '18 at 21:09
source share

Save as data:

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

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

To load an image into imageView: Look at the exclamation mark "!", "?" is it cramped like that.

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

The NSData type is automatically converted to a data type during this process.

+7
Apr 20 '17 at
source share

For safe code execution, use the if-let block with Data to prevent the & application from crashing, since the UIImagePNGRepresentation function returns an optional value.

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

Note. Data refers to the Swift 3+ class. Use data instead of NSData with Swift 3+

Common image operations (e.g. png and 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... } } 

Using the 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... } } 
+6
Nov 02 '17 at 10:42 on
source share

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

Image Data: -

  let image = UIImage(data: pngData) 
+4
Nov 15 '18 at 5:45
source share

More details

  • Xcode 10.2.1 (10E1001), Swift 5

Solution 1

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



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

Using Solution 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

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

Using Solution 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

Presenting an image will take up a lot of processor and memory resources. So, in this case, it is better to follow a few rules:

- do not run jpegData (compressionQuality :) in the main queue

- run only one jpegData (compressionQuality :) at a time

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

On 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

+3
Apr 24 '19 at 21:51
source share

Swift 5

let the image you create as UIImage be the image

 image.pngData() as NSData? 
0
Sep 27 '19 at 19:56 on
source share



All Articles