23

I'm trying to save a UIIMage and then retrieve it and display it. I've been successful by saving an image in the bundle, retrieving it from there and displaying. My problem comes from when I try to save an image to disk (converting it to NSData), then retrieving it. I convert the image to NSData like so...

NSData* topImageData = UIImageJPEGRepresentation(topImage, 1.0);

then I write it to disk like so...

[topImageData writeToFile:topPathToFile atomically:NO];

then I tried to retrieve it like so...

topSubView.image = [[UIImage alloc] initWithContentsOfFile:topPathToFile];

which returns no image (the size is zero). so then I tried...

NSData *data = [[NSData alloc] initWithContentsOfFile:topPathToFile];
topSubView.image = [[UIImage alloc] initWithData:data];

to no avail. When I step through the debugger I do see that data contains the correct number of bytes but I'm confused as to why my image is not being created. Am I missing a step? Do I need to do something with NSData before converting to an image?

Krunal
  • 77,632
  • 48
  • 245
  • 261
bruin
  • 245
  • 1
  • 2
  • 6

5 Answers5

34

Try this code. This worked for me.

Saving the data.

create path to save the image.

let libraryDirectory = NSSearchPathForDirectoriesInDomains(.libraryDirectory,
                                                               .userDomainMask,
                                                               true)[0]
let libraryURL = URL(fileURLWithPath: libraryDirectory, isDirectory: true)
let fileURL = libraryURL.appendingPathComponent("image.data")

convert the image to a Data object and save it to the file.

let data = UIImageJPEGRepresentation(myImage, 1.0)
try? data?.write(to: fileURL)

retrieving the saved image

let newImage = UIImage(contentsOfFile: fileURL.relativePath)

Create an imageview and load it with the retrieved image.

let imageView = UIImageView(image: newImage)
self.view.addSubview(imageView)
ArunGJ
  • 2,685
  • 21
  • 27
  • image to NSData worked for me like that: NSData *data = [NSData dataWithData:UIImagePNGRepresentation(myImage)]; – madmax May 29 '11 at 14:55
  • This NSData* data = UIImageJPEGRepresentation(myImage, 1.0); is wrong. – madmax May 29 '11 at 14:56
  • Yes i tried and it doesn't create the data for me. And i think it is the correct way to allocate an NSData Object. – madmax May 29 '11 at 17:28
  • i tried the code before posting it here. it worked 100% for me. To create an nsdata object, there are a number of ways. you cant say some are wrong. – ArunGJ May 29 '11 at 17:46
  • The only problem for me is that UIImageJPEGRepresentation is too slow. It takes 4-5 seconds for 1.5 MB image. – Martin Berger Sep 18 '12 at 08:26
  • is it a JPG or PNG you want to convert to NSData? I see both ( UIImagePNGRepresentation and UIImageJPEGRepresentation ) above and they're not interchangeable. you must use the appropriate method for the respective format. – iksnae May 20 '13 at 20:49
19

You should be able to use class methods of UIImage

[UIImage imageWithContentsOfFile:topPathToFile]; 

OR

[UIImage imageWithData:data];

Did that not work?

Hope this helps!

Kartik Shah
  • 932
  • 4
  • 9
  • Thanks for the response but I got the same result. Still no image. I'm really stumped right now. – bruin Feb 11 '10 at 05:14
8

Just in case this helps someone, from iOS6 we have the imageWithData:scale method. To get an UIImage with the right scale from an NSData object, use that method, declaring the scale you use to store the original image. For example:

CGFloat screenScale = [[UIScreen mainScreen] scale];
UIImage *image = [UIImage imageWithData:myimage scale:screenScale];

Here, myimage is the NSData object where you stored the original image. In the example, I used the scale of the screen. If you use another scale for the original image, use that value instead.

Mikiko Jane
  • 463
  • 6
  • 13
0

Use if-let block with Data to prevent app crash & safe execution of code, as function UIImagePNGRepresentation returns an optional value.

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

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

Generic image operations (like png & jpg both):

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

    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...
     }
}
Krunal
  • 77,632
  • 48
  • 245
  • 261
0

Check this out: http://www.nixwire.com/getting-uiimage-to-work-with-nscoding-encodewithcoder/.

It has exactly what I think the solution to your problem is. You can't just make an image out of NSData, even though that's what common sense suggests. You have to use UIImagePNGRepresentation. Let me know if this helps.

Dylan Gattey
  • 1,713
  • 13
  • 34