未加载资产文件夹中的 HEIC 图像

HEIC images within the assets folder not loaded

我已经在我的项目 xcassets 文件夹中设置了 .heic 个图像,以保存一些 space。但是我无法通过 UIImage(named:) 构造函数加载它们。我总是得到 nil,所以我必须加载它们的唯一方法是指定 URL。你知道为什么吗?

imageView.image = UIImage(named: "stone") // This returns nil.

同样,如果我将它们作为文件添加到项目中并通过这种方法访问它们,我创建的一切都很好(或使用像 SDWebImage 这样的库),但我相信我正在失去应用程序瘦身的力量,因为图像作为文件托管,例如iPhone 7 将同时具有 2x3x 分辨率,而只需要 2x

extension UIImage {

    convenience init?(heicName: String, useScale: Bool = false) {
        guard let resourcePath = Bundle.main.path(forResource: heicName.fileName(fileExtension: .heic, useScale: useScale), ofType: nil) else {
            return nil
        }

        let url = URL(fileURLWithPath: resourcePath) as CFURL

        guard let source = CGImageSourceCreateWithURL(url, nil),
            let image = CGImageSourceCreateImageAtIndex(source, 0, nil) else {
                return nil
        }

        self.init(cgImage: image)
    }

}

所以我的问题是,任何人都可以向我解释使用 HEIC 作为图像资产文件夹中托管的图像并使其与应用程序瘦身兼容的过程(只需获取所需的资源,即 2x、3x)吗?

更新: 经过更多研究后,我意识到当我在图像视图上设置图像名称时,图像是从 IB 加载的。你知道这在内部是如何工作的吗? IB 使用哪个构造函数将 UIImage 设置为 UIImageView?

更新 2: 我已经向 Apple 提交了一个雷达: Radar

Apple 的资产编译器 re-encodes 所有以各种内部格式进入其中的图像,一些是标准的,一些是专有的,取决于一系列因素,包括图像类型、目标 OS 版本,可能还有其他因素。不幸的是,在撰写本文时,就 HEIC 文件而言,资产编译器似乎存在问题;如果我尝试将 HEIC 文件放入资产目录,它似乎被排除在外。图像数据没有复制到 Assets.car 文件中,文件本身只有 16 KB,只包含一些空的 B-trees。因此,当您尝试使用 UIImage 加载图像时,您什么也得不到。

幸运的是,由于资产编译器会重新编码输入其中的所有图像 无论如何,您可以 re-encode 将图像转换为另一种格式(我推荐 PNG,因为它是无损),end-user 接收到的结果文件应该与 HEIF 输入文件相同(具有讽刺意味的是,它可能最终被编码为 HEIF,因为资产格式支持它)。所以这就是我要做的,直到 Apple 修复资产编译器中的这个错误。

通过 Radar 和 Apple DTS 进行大量研究后,我收到了一位联系其他工程团队的工程师的以下答复:

“嗨,

我的电子邮件开始了一个很长的电子邮件线程,涉及许多工程师通过系统跟踪您的问题。最终,他们发现目前使用 jpg 和 png 文件的图像资产和系统的其他部分不支持 HEIC 格式。具体来说,我指的是自动加载的资源,例如保存在情节提要中的资源或其他 Xcode 生成的资源和文件。目前没有可用的解决方法。

这并不意味着您不能在您的应用中使用 HEIC 图像。如果您想在代码中使用 HEIC 图片,则可以使用 Image I/O 加载图片。

请在以后的操作系统版本中重试。”

长话短说:

还不能在资产文件夹上使用 HEIF。也许在未来。

更新:

在 Xcode 10 beta 5 上测试,现在 Assets.car 包含 HEIF 图像,这表明可以将 HEIF 图像用作资产文件夹的一部分。