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

9

我在我的项目的xcassets文件夹中设置了一些.heic图像以节省空间。然而,我无法通过UIImage(named:)构造函数加载它们。每次都返回nil,因此我只能通过指定URL来加载它们。您有任何想法吗?

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

xcassets文件夹

如果我将它们作为文件添加到项目中,并通过我创建的方法访问它们,或使用像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

我没有HEIC格式的图片。请问你能告诉我从哪里下载吗? - Sagar Chauhan
你不能这样做,因为assets不支持heic格式。 你可以将heic转换为JPG / PNG格式。 请阅读此文档:https://devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/511_working_with_heif_and_hevc.pdf。 - a.masri
1
@a.masri,HEIC被资产支持,请参阅苹果文档 - Daniel
然而,它与UIImage和应用程序瘦身不兼容。 - Daniel
丹尼尔,你知道IB在将UIImage分配给UIImageView输出时的工作原理吗?从资产文件夹中使用Heic格式可以正常工作,但我不知道设置UIImageView中图像的内部机制是什么。 - jomafer
显示剩余2条评论
3个回答

1
苹果的资源编译器会以多种内部格式重新编码所有输入的图像,其中一些是标准的,另一些是专有的,这取决于许多因素,包括图像类型、目标操作系统版本和可能的其他因素。不幸的是,在撰写本文时,资产编译器似乎在处理HEIC文件方面存在缺陷;如果我尝试将HEIC文件放入资源目录中,它似乎被省略了。图像数据未复制到Assets.car文件中,该文件本身仅为16 KB大小,仅包含几个空B树。因此,当您尝试使用UIImage加载图像时,您将得到空白。
幸运的是,由于资源编译器无论如何都会重新编码所有输入的图像,因此您可以将图像重新编码为另一种格式(我建议使用PNG,因为它是无损的),并且最终用户收到的结果文件应与使用HEIF输入文件相同(具有讽刺意味的是,它可能最终会被编码为HEIF,因为资源格式支持它)。所以在苹果修复资产编译器中的这个错误之前,这就是我会做的事情。

你确定吗?如果你创建了“新图像集”,并将HEIC图像拖到其中(1x、2x或3x),你会在资源文件夹中看到它,就在contents.json文件旁边。 - jomafer
1
@jomafer 在源代码目录中,是的。但你有在编译后的二进制文件中查找吗?当我这样做时,它不在里面。 - Charles Srstka
我向苹果公司反映了这个问题,他们告诉我可以使用ImageIO框架从资源文件夹中访问HEIC图像,但我不知道如何获取资源文件夹中的URL以便使用"CGImageSourceCreateWithURL"。你有什么想法吗? - jomafer
肯定的,你是正确的。我尝试了几种方法将资源添加到资源文件夹中,但HEIC图像没有包含在IPA中。 - jomafer
@jomafer IPA中没有资产文件夹。资产目录中的所有图像都被重新编码并复制到专有格式的Assets.car文件中。不幸的是,HEIC文件似乎无法进入该文件,我大约99%确定这是一个错误。因此,在修复之前的临时解决方法是,您可以将重新编码的PNG文件放入资产目录中,或者将图像从资产目录中取出,并将它们作为普通资源包含在内(然后通过“Bundle”API获取URL)。 - Charles Srstka
抱歉,我指的是Assets.car文件。我已经打开了,并且如您所确认,HEIC图像不存在。苹果公司的某位工作人员告诉我,对于他们来说,HEIC是相对较新的格式,他们可能尚未支持该格式。因此我将继续使用Radar。 我会随时向您更新。 - jomafer

0

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

“您好,

我的电子邮件引发了一长串涉及多名工程师的邮件讨论,他们通过系统追踪您的问题。最终,他们发现 HEIC 格式在图像资源和其他部分当前不支持使用,目前仅支持使用 jpg 和 png 文件。具体而言,我指的是自动加载的资源,例如保存在 Storyboard 或其他 Xcode 生成的资源和文件中的资源。目前没有可用的解决方法。

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

请在将来的操作系统版本中再试一次。”

TL;DR:

目前还不能在资源文件夹中使用 HEIF。也许在未来会有所改变。

更新:

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


0
  • Xcode 15.0 Beta 5
  • iOS17.0
  • 第一步:将HEIF图像文件扩展名更改为.heif,例如:xxx.HEIC -> xxx.heif
  • 第二步:将文件拖动到Xcode项目文件夹中
  • 第三步:进入项目设置,选择"Build Phases- Copy Bundle Resources",添加xxx.heif文件
  • 最后,我可以使用CGImageSourceCreateWithData函数(使用Bundle.main.path获取路径,然后使用NSData contentsOfFile)读取图像。

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


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