如何将 UIImage 保存到文档目录?

Posted

技术标签:

【中文标题】如何将 UIImage 保存到文档目录?【英文标题】:How to save a UIImage to documents directory? 【发布时间】:2017-03-25 13:02:30 【问题描述】:

我正在尝试将录制的视频的文件路径和视频中的缩略图保存到文档目录中。然后,使用文件路径将这两个值设置为一个对象,以便我可以使用该对象来填充集合视图。使用我目前拥有的代码(如下),在我录制视频后,视频路径将保存到文档目录,视频路径和缩略图设置为我的 Post 对象,缩略图正确显示在我的收藏视图中.到目前为止一切顺利。

但是,只有视频路径在应用重新启动之间仍然存在,因为它在目录中,而缩略图不在。我也想将缩略图保存在那里,但我不知道该怎么做,因为您似乎只能将 URL 写入目录。

这是我使用文档目录的第一次体验,因此我们将不胜感激!如何将缩略图 (UIImage) 连同其来源的视频一起写入我的文档目录?

到目前为止,这是我的代码:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 

    let mediaType = info[UIImagePickerControllerMediaType] as! NSString
    dismiss(animated: true, completion: nil)

    if mediaType == kUTTypeMovie 
        // Componenets for a unique ID for the video
        var uniqueVideoID = ""
        var videoURL:NSURL? = NSURL()
        var uniqueID = ""
        uniqueID = NSUUID().uuidString

        // Get the path as URL
        videoURL = info[UIImagePickerControllerMediaURL] as? URL as NSURL?
        let myVideoVarData = try! Data(contentsOf: videoURL! as URL)

        // Write the video to the Document Directory at myVideoVarData (and set the video's unique ID)
        let docPaths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentsDirectory: AnyObject = docPaths[0] as AnyObject
        uniqueVideoID = uniqueID  + "VIDEO.MOV"
        let docDataPath = documentsDirectory.appendingPathComponent(uniqueVideoID) as String
        try? myVideoVarData.write(to: URL(fileURLWithPath: docDataPath), options: [])
        print("docDataPath under picker ", docDataPath)
        print("Video saved to documents directory")

        // Create a thumbnail image from the video (first frame)
        let asset = AVAsset(url: URL(fileURLWithPath: docDataPath))
        let assetImageGenerate = AVAssetImageGenerator(asset: asset)
        assetImageGenerate.appliesPreferredTrackTransform = true
        let time = CMTimeMake(asset.duration.value / 3, asset.duration.timescale)
        if let videoImage = try? assetImageGenerate.copyCGImage(at: time, actualTime: nil) 
            // Add thumbnail & video path to Post object
            let video = Post(pathToVideo: URL(fileURLWithPath: docDataPath), thumbnail: UIImage(cgImage: videoImage))
            posts.append(video)
            print("Video saved to Post object")
        
    

【问题讨论】:

您正在本地生成图像并将其保存到您的对象中,因为图像没有直接保存在文档中或缓存在任何数据库中..您将无法取回..您可以做什么是让您的缓存管理器将图像保存在DocumentDirectory 中,然后您可以以与视频相同的方式保存该 URL,或者将图像的 NSData 保存在数据库中并将其渲染回 UIImage .. 【参考方案1】:

一个建议:如果可以按照苹果的指南再次下载,请将图像保存到库/缓存中。


就这么简单:

func saveImageToDocumentDirectory(_ chosenImage: UIImage) -> String 
        let directoryPath =  NSHomeDirectory().appending("/Documents/")
        if !FileManager.default.fileExists(atPath: directoryPath) 
            do 
                try FileManager.default.createDirectory(at: NSURL.fileURL(withPath: directoryPath), withIntermediateDirectories: true, attributes: nil)
             catch 
                print(error)
            
        
        let filename = NSDate().string(withDateFormatter: yyyytoss).appending(".jpg")
        let filepath = directoryPath.appending(filename)
        let url = NSURL.fileURL(withPath: filepath)
        do 
            try UIImageJPEGRepresentation(chosenImage, 1.0)?.write(to: url, options: .atomic)
            return String.init("/Documents/\(filename)")

         catch 
            print(error)
            print("file cant not be save at path \(filepath), with error : \(error)");
            return filepath
        
    

Swift4:

func saveImageToDocumentDirectory(_ chosenImage: UIImage) -> String 
        let directoryPath =  NSHomeDirectory().appending("/Documents/")
        if !FileManager.default.fileExists(atPath: directoryPath) 
            do 
                try FileManager.default.createDirectory(at: NSURL.fileURL(withPath: directoryPath), withIntermediateDirectories: true, attributes: nil)
             catch 
                print(error)
            
        

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyyMMddhhmmss"

        let filename = dateFormatter.string(from: Date()).appending(".jpg")
        let filepath = directoryPath.appending(filename)
        let url = NSURL.fileURL(withPath: filepath)
        do 
            try chosenImage.jpegData(compressionQuality: 1.0)?.write(to: url, options: .atomic)
            return String.init("/Documents/\(filename)")

         catch 
            print(error)
            print("file cant not be save at path \(filepath), with error : \(error)");
            return filepath
        
    

【讨论】:

谢谢,所以这是将其转换为字符串然后保存?看起来它可以工作,但我在let filename = NSDate().string(withDateFormatter: yyyytoss).appending(".jpg") 线上遇到错误,yyyytoss 似乎无法识别。 yyyytoss 是 dateformater 格式,即“yyyyMMddhhmmss”,你可以使用任何一种,但这对我来说是最好的 另外,当我将缩略图保存到我的 Post 对象 (let video = Post(pathToVideo: URL(fileURLWithPath: docDataPath), thumbnail: UIImage(cgImage: videoImage))) 时,我需要将它保存为这个文件路径,而不仅仅是一个 UIImage,我该如何使用返回的文件路径在里面? 是的,我正在返回从文档中保存图像的文件路径...不要保存完整路径,路径前缀可以更改。 所以我在保存到对象之前调用saveImageToDocumentDirectory(UIImage(cgImage: videoImage)),但我想知道现在要传递给对象而不是UIImage(cgImage: videoImage),即如何引用文件路径

以上是关于如何将 UIImage 保存到文档目录?的主要内容,如果未能解决你的问题,请参考以下文章

无法从 iPhone 文档目录位置中的已保存文件重新加载 UIImage

UIImage无法保存到文档文件夹ios

将表示图像的 NSMutableData 保存到 iPhone 照片库

将 UIIMage 中显示的照片自动保存到目录

退出并加载我的应用程序时,如何将图像保存并读取到临时文件夹

如何在图像上写文字并保存