【问题标题】:UIImageJPEGRepresentation returns nil when file at specified path is deleted in Swift?在 Swift 中删除指定路径的文件时,UIImageJPEGRepresentation 返回 nil?
【发布时间】:2017-06-04 03:44:45
【问题描述】:

我完全不知道UIImageJPEGRepresentation 与 Documents 目录中文件路径的关系。

基本上,当我从文件路径中删除一个文件,然后在UIImage 上调用UIImageJPEGRepresentation 时,它返回nil,但如果文件路径没有被删除,UIImageJPEGRepresentation 返回图像的数据表示.

这是我的示例代码来说明我的意思:

func functionA()
{
    if imagePaths_ARRAY.isEmpty == false
    {
        for pathToDelete in imagePaths_ARRAY
        {
            if fileManager.fileExists(atPath: pathToDelete)
            {
                do
                {
                    try fileManager.removeItem(atPath: pathToDelete)
                }
                catch let error as NSError
                {
                    print(error.localizedDescription)
                }
            }
            else
            {
                print("ERROR")
            }
        }

        imagePaths_ARRAY.removeAll()
    }

    print(images_ARRAY)

    for image in images_ARRAY
    {
        print(image)

        if let imageData = UIImageJPEGRepresentation(image, 0.5)
        {
            print("RETURN GOOD")
            let imageName = getImageName()

            let imagePath = getDirectoryPath().appending("/" + imageName)

            let success = fileManager.createFile(atPath: imagePath, contents: imageData, attributes: nil)

            if success == true
            {
                imagePaths_ARRAY.append(imagePath)
            }
        }
        else
        {
            print("RETURN NIL")
        }

    }
}

FIRST时间functionA 被调用,imagePaths_ARRAY 为空,因此内部代码块不会执行。我循环遍历UIImages 的数组,对于每个图像,我调用UIImageJPEGRepresentation 将其转换为Data 对象以写入文件,并将imagePath 添加到我的imagePaths_ARRAY 数组以在其他地方使用在我的代码中。

对于每张图片,我都会看到RETURN GOOD 的日志,并且所有图片都被写入文件。

但是,当functionA被称为SECOND的时候,imagePaths_ARRAY不为空,所以我删除了imagePaths_ARRAY中路径下的所有文件。

但是当UIImageJPEGRepresentation 再次在image 上调用时,它返回nil?

我完全不知道为什么,因为images_ARRAY 中的每个image 都给了我一个有效的UIImage

[<UIImage: 0x600000085280> size {4288, 2848} orientation 0 scale 1.000000]

如第一句所述,我想知道使用removeItem 删除文件如何导致UIImageJPEGRepresentation 返回nil?

更新:当我将 UIImageJPEGRepresentation 替换为 UIImagePNGRepresentation 时,图像被压缩得很好。我完全糊涂了!

【问题讨论】:

  • 你为什么要删除路径?
  • @Optimus:需要删除路径才能在我的应用中执行其他功能
  • 在调用functionA 之间,您是否对您的images_ARRAY 做任何事情?如果是这样,那可能就是问题所在 - 您的图像数据可能不再采用“jpeg 表示”的格式。尝试减少调试问题的发生...
  • @DonMag 我在通话之间没有对images_ARRAY 做任何其他事情。如果我评论如何检查imagePaths_ARRAY.isEmpty == false,那么UIImageJPEGRepresentation 的转换没有问题,或者甚至只是注释掉try fileManager.removeItem(atPath: pathToDelete) 并且它工作正常。

标签: ios swift uiimagejpegrepresentation


【解决方案1】:

您的代码中似乎还有其他必须

我刚刚试了一下,使用以下代码,我可以反复点击按钮,每次都成功:

//
//  TestViewController.swift
//

import UIKit

class TestViewController: UIViewController {

    var imagePaths_ARRAY = [String]()
    var images_ARRAY = [UIImage]()

    let fileManager = FileManager.default

    override func viewDidLoad() {
        super.viewDidLoad()

        let names = ["s1", "s2", "s3"]

        for s in names {
            if let img = UIImage(named: s) {
                images_ARRAY.append(img)
            }
        }
    }

    @IBAction func btnTapped(_ sender: Any) {
        functionA()
    }


    func getDirectoryPath() -> String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    }

    func getImageName() -> String {
        let randomNum:UInt32 = arc4random_uniform(1000000)
        return "randomName_\(randomNum)"
    }

    func functionA()
    {

        print(imagePaths_ARRAY)

        if imagePaths_ARRAY.isEmpty == false
        {
            for pathToDelete in imagePaths_ARRAY
            {
                if fileManager.fileExists(atPath: pathToDelete)
                {
                    do
                    {
                        try fileManager.removeItem(atPath: pathToDelete)
                    }
                    catch let error as NSError
                    {
                        print(error.localizedDescription)
                    }
                }
                else
                {
                    print("ERROR")
                }
            }

            imagePaths_ARRAY.removeAll()
        }

        print(images_ARRAY)

        for image in images_ARRAY
        {
//          print(image)

            if let imageData = UIImageJPEGRepresentation(image, 0.5)
            {
                let imageName = getImageName()

                let imagePath = getDirectoryPath().appending("/" + imageName)

                let success = fileManager.createFile(atPath: imagePath, contents: imageData, attributes: nil)

                if success == true
                {
                    print("RETURN GOOD")
                    imagePaths_ARRAY.append(imagePath)
                }
            }
            else
            {
                print("RETURN NIL")
            }

        }

    }

}

【讨论】:

  • 只是为了澄清,因为我没有机会测试代码,但是当你点击一个按钮时,我可以看到代码所做的第一件事就是删除每个指向 pathToDelete 的文件,然后循环通过images_ARRAY并调用UIImageJPEGRepresentation,与我的代码完全相同,但您说它从不输出RETURN NIL,即它成功地将图像写入文件?
  • 正确...它每次都打印“RETURN GOOD”。
  • 目前正在查看我的代码,但我很好奇,为什么您认为 UIImageJPEGRepresentation 返回 nil.... 显然在转换之前,我确实看到一个有效的 UIImage 被传递到函数,所以我很困惑为什么不能转换UIImage ..我知道你说“你的图像数据可能不再是可以用 jpeg 表示的格式”..你能详细说明一下你的内容吗什么意思?
  • 查看 Apple 的文档,可能有几个原因。不过,有些东西让我想起了——您的原始帖子显示size {4288, 2848} ...您要在images_ARRAY 中保留多少这样大小的图像?您是否可能内存不足,而图像 reference 有效,但图像 data 实际上不在内存中?
  • 我想我必须查看您的其余代码才能尝试找出答案...您可以创建一个复制问题的小型示例项目吗?
猜你喜欢
  • 2015-06-26
  • 2020-01-20
  • 2018-07-08
  • 2014-08-20
  • 1970-01-01
  • 2021-10-22
  • 2012-02-07
  • 2018-05-09
  • 1970-01-01
相关资源
最近更新 更多