2

I have a UIImage array that I'm trying to save to disk (documents directory). I've converted it to Data so it can be saved but I can't figure out the correct/best way to save that [Data] to disk.

(arrayData as NSArray).write(to: filename, atomically: false) doesn't seem right or there seems like there is some better way.

Code so far:

    // Get the new UIImage
    let image4 = chartView.snapShot()

    // Make UIImage into Data to save
    let data = UIImagePNGRepresentation(image4!)

    // Add Data image to Data Array
    arrayData.append(data!)

    // Get Disk/Folder
    let filename = getDocumentsDirectory().appendingPathComponent("images")

    // This is how I'd Write Data image to Disk
    // try? data?.write(to: filename)

    // TODO: Write array Data images to Disk
    (arrayData as NSArray).write(to: filename, atomically: false)
1
  • 1
    let whatever: NSMutableArray = arrayData as! NSMutableArray whatever.write(toFile: filename, atomically: true) Commented Jul 4, 2017 at 21:22

2 Answers 2

3

To save your images to the document directory, you could start by creating a function to save your image as follows. The function handles creating the image name for you and returns it.

    func saveImage(image: UIImage) -> String {

    let imageData = NSData(data: UIImagePNGRepresentation(image)!)
    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,  FileManager.SearchPathDomainMask.userDomainMask, true)
   let docs = paths[0] as NSString
   let uuid = NSUUID().uuidString + ".png"
   let fullPath = docs.appendingPathComponent(uuid)
   _ = imageData.write(toFile: fullPath, atomically: true)
  return uuid

   }

Now since you want to save an array of images, you can simply loop and call the saveImage function:

   for image in images { 
       saveImage(image: image)
   }

If you prefer to name those images yourself, you can amend the first function to the following:

    func saveImage(image: UIImage, withName name: String) {

 let imageData = NSData(data: UIImagePNGRepresentation(image)!)
 let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,  FileManager.SearchPathDomainMask.userDomainMask, true)
 let docs = paths[0] as NSString
 let name = name
 let fullPath = docs.appendingPathComponent(name)
 _ = imageData.write(toFile: fullPath, atomically: true)
 }

When you save an image as a UIImagePNGRepresentation as you are trying to do, please note that is does not save orientation for you. This means that when you attempt to retrieve the image, it might be titled to the left. You will need to redraw your image to make sure it has the right orientation as this post will explain how to save png correctly. However, if you save your image with UIImageJPEGRepresentation you will not have to worry about all that and you can simply save your image without any extra effort.

EDITED TO GIVE ARRAY OF IMAGES

To retrieve the images you have saved, you can use the following function where you pass an array of the image names and you get an array back:

   func getImage(imageNames: [String]) -> [UIImage] {

    var savedImages: [UIImage] = [UIImage]()

    for imageName in imageNames {

    if let imagePath = getFilePath(fileName: imageName) {
        savedImage.append(UIImage(contentsOfFile: imagePath))
    }

   }

   return savedImages

   }

Which relies on this function to work:

    func getFilePath(fileName: String) -> String? {

    let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
    let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
    var filePath: String?
    let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
   if paths.count > 0 {
   let dirPath = paths[0] as NSString
   filePath = dirPath.appendingPathComponent(fileName)
   }
  else {
  filePath = nil
  }

  return filePath
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Marked your answer but I'm not seeing that you show how to retrieve the array, I'm only seeing that you would be able to retrieve 1 image?
I assumed the question was about how to save the image based off what you emphasized about the "correct/best way to save that [Data] to disk". I only added the retrieve part in case you did not know how. But no worries, I have amended the answer to help you get the images by passing an array of image names and getting an array of images you saved back. Hope this helps.
Yeah I marked your answer because you answered what I needed, but thanks for going the extra mile and adding the retrieving too now! Works!
1

You can below code to stored image into local.

   let fileManager = NSFileManager.defaultManager()
    let paths = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("ImageName.png")
    let image = YOUR_IMAGE_TO_STORE.
    let imageData = UIImageJPEGRepresentation(image!, 0.5)
    fileManager.createFileAtPath(paths as String, contents: imageData, attributes: nil)

2 Comments

Thanks for the response! From you're code it looks like you are taking about only storing an image, not an array of images. Do you know how to store an array of images?
You can use into loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.