Swift 3 - 保存图片替代

Posted

技术标签:

【中文标题】Swift 3 - 保存图片替代【英文标题】:Swift 3 - Save image alternative 【发布时间】:2017-06-19 21:15:40 【问题描述】:

我需要找到此方法的替代方法来保存图像

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 分钟)。

【问题讨论】:

首先,UserDefaults 是您存储大文件的最后一个位置。其次,synchronize() 基本上是无意义的。第三,您可能希望使用CoreData 进行图像/数据存储 为什么需要将它保存在 UserDefaults 中?这不是 UserDefaults 的用途。 @Mr.Xcoder 如何使用 CoreData 保存和加载图像? @totiG 我应该用什么来保存和加载它? 【参考方案1】:

不建议将图像等大文件保存到 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
    

【讨论】:

感谢@gwinyai,你的方法很棒,但我有一个问题^^当我恢复图像时,它向左转了 90 度,你知道为什么吗? 是的,我以前遇到过这个问题,但由于某种原因,我不记得修复了。您能否尝试使用 UIImageJPEGRepresentation 将图像保存为 JPEG 并尝试一下。我给你的函数用 UIImagePNGRepresentation 保存为 PNG。我只需要一些来记住那个 90 问题的一些细节。 @Rombond PNG 不保存任何方向。您需要在保存之前重新绘制图像。 @gwinyai 与 JPEG 图像它完美地工作再次感谢 感谢@LeoDabus,但我更喜欢使用JPEG图像,它的行代码更少^^【参考方案2】:

UserDefaults 是存储一小部分数据(如用户偏好)的地方。 UserDefaults 的空间非常有限,而且速度可能很慢。就你而言,你提到这是 5-10 分钟,但我对此表示怀疑。

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

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

【讨论】:

以上是关于Swift 3 - 保存图片替代的主要内容,如果未能解决你的问题,请参考以下文章

保存旋转的图片(swift3)

swift 保存图片

保存照片并检索资产时,应用图片中的 Swift Camera 不保存 GPS 信息?

保存图片到相册的解决方法

img图片无法显示利用onerror事件显示替代图片

swift 将图片保存到自定义相册中