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

9
我正试图将一个录制视频的文件路径和缩略图保存到文档目录中。然后,使用这些文件路径将这两个值设置为一个对象,以便我可以使用该对象来填充集合视图。使用我当前的代码(如下),在我录制视频后,视频路径被保存到文档目录中,并且视频路径和缩略图被设置到我的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。 - Ankit
1个回答

19

一个建议:按照苹果的指导方针,如果可以再次下载,请将图像保存到Library/Caches中。


就这么简单:

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

另外,当我将缩略图保存到我的Post对象中(let video = Post(pathToVideo: URL(fileURLWithPath: docDataPath), thumbnail: UIImage(cgImage: videoImage))),现在我需要将其保存为文件路径而不仅仅是UIImage,那么我该如何在其中使用返回的文件路径呢? - KingTim
是的,我正在返回文件路径,在其中我们的图像从文档保存...不保存完整路径,路径前缀可以更改。 - Ashwin Kanjariya
所以在保存到对象之前,我调用了 saveImageToDocumentDirectory(UIImage(cgImage: videoImage)),但现在我想知道在对象中传递什么而不是 UIImage(cgImage: videoImage),即如何引用文件路径。 - KingTim
日期格式化程序一直给我错误,似乎无法识别我提供的任何内容。也许这是Swift 3的变化? - KingTim
好的,那么它将其保存为字符串,所以我将把我的帖子对象中的缩略图更改为字符串。现在我需要使用这些缩略图来填充我的集合视图图像视图,那么我该如何在此处使用文件路径中的UIImage cell.postImage.image = posts[indexPath.row].thumbnail - KingTim
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接