Swift 3 - 保存图像替代方案

时间:2017-06-19 21:15:41

标签: ios swift uiimageview save nsuserdefaults


我需要找到一种替代方法来保存图像

let save = UserDefaults.standard
let imageData = UIImageJPEGRepresentation(Photo.image!, 1.0)
save.set(imageData, forKey: "Image")
save.synchronize()
if let imgData = save.object(forKey: "Image"){
     let compressedJPGImage = UIImage(data: imgData as! Data)
}

并加载图片

let imgData = save.object(forKey: "Image")
let compressedJPGImage = UIImage(data: imgData as! Data)
Photo.image = compressedJPGImage

这种方法存在的问题是我在UserDefaults.standard中保存了很多其他值,因此在同步时需要花费很多时间(5-10分钟)。

2 个答案:

答案 0 :(得分:4)

不建议将大型文件(如图像)保存到UserDefaults。 UserDefaults旨在保存非常小的数据,例如用户首选的主题颜色。也许合适的替代方法是将图像保存在文档目录中。这是一个允许您保存图像的功能:

    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

   }

上述功能将为您创建已保存图像的名称。如果您希望指定要保存的图像的名称,则可以执行以下操作(但您将负责确保您指定的图像名称是唯一的):

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

要检索这些图像,您可以将图像名称传递给此功能:

     func getImage(imageName: String) -> UIImage? {

     var savedImage: UIImage?

     if let imagePath = getFilePath(fileName: imageName) {
     savedImage = UIImage(contentsOfFile: imagePath)
     }
     else {
    savedImage = nil
     }

    return savedImage

    }

依赖于此功能:

    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
   }

以下是您现在如何保存图片而不是UserDefaults的示例。我正在保存一个我将调用的图像"图像":

    saveImage(image: Photo.image, withName name: "Image")

以下是我将如何检索已保存图片的示例:

    if let theSavedImage = getImage(imageName: "Image") {
        //I got the image
    }

答案 1 :(得分:0)

UserDefaults是存储一小部分数据(如用户首选项)的地方。 UserDefaults的空间非常有限,可能会非常慢。在你的情况下,你提到它是5-10分钟,我怀疑。

如果您希望跨应用程序的会话(持久存储)存储图像,则应考虑使用文件系统(Application_Folder / Library / Cache /)或Core Data框架。访问图像时,您将获得更好的性能。

如果不需要保留图像并且需要为应用的单个会话存储图像,则应使用imageNamed:类的UIImage API。此API将映像加载到内存中并将其保留在系统缓存中。对于所有连续访问,它仅指缓存图像。如果要加载太多图像,这将增加系统缓存大小和应用程序的内存占用。另一个API是imageWithContentsOfFile:。与第一个API不同,此API将始终在内存中加载新的图像实例。释放图像实例后将释放内存,而第一个API则不是这样。