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

问题描述 投票:0回答:3

我已在项目中的

.heic
文件夹中设置
xcassets
图像以节省一些空间。但是我无法通过
UIImage(named:)
构造函数加载它们。我总是得到
nil
,所以加载它们的唯一方法是指定 URL。你知道为什么吗?

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

再次,如果我将它们作为文件添加到项目中,并通过这种方法访问它们,我创建的一切都很好(或使用像 SDWebImage 这样的库),但我相信我正在失去应用程序精简的能力,因为图像托管为文件,例如当只需要

2x
时,iPhone 7 将同时具有
3x
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: 我已经向苹果提交了雷达: 雷达

swift xcode assets heif heic
3个回答
1
投票

Apple 的资产编译器以各种内部格式(一些标准格式和一些专有格式)重新编码进入其中的所有图像,具体取决于一系列因素,包括图像类型、目标操作系统版本以及可能的其他因素。不幸的是,在撰写本文时,资产编译器似乎在 HEIC 文件方面存在缺陷;如果我尝试将 HEIC 文件放入资产目录中,它似乎被排除在外。图像数据不会复制到 Assets.car 文件中,该文件本身大小只有 16 KB,仅包含一些空 B 树。因此,当您尝试使用

UIImage
加载图像时,您什么也得不到。

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


0
投票

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

“嗨,

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

这并不意味着您不能在应用程序中使用 HEIC 图像。如果您想在代码中使用 HEIC 图像,那么您可以使用图像 I/O 来加载图像。

请在未来版本的操作系统中重试。”

TL;博士:

目前还无法在资产文件夹上使用 HEIF。也许在未来。

更新:

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


0
投票

Xcode 15.0 测试版 5 iOS17.0 第一步:将HEIF图像文件扩展名更改为.heif xxx.HEIC -> xxx.heif 第二步:将文件拖入xcode项目文件夹中 第三步:进入项目设置Build Phases-Copy Bundle Resources,添加xxx.heif文件 最后,我可以使用 CGImageSourceCreateWithData 读取图像(使用 Bundle.main.path 获取路径,然后使用 NSDatacontentsOfFile)。

请注意,这可能不是最佳实践!

© www.soinside.com 2019 - 2024. All rights reserved.