HEIC images within the assets folder not loaded
Asked Answered
N

3

9

I have set .heic images in my xcassets folder from my project to save some space. However I'm not able to load them through the UIImage(named:) constructor. I'm always getting nil, so the only way I have to load them is by specifying the URL. Do you have any idea why?

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

xcassets folder

Again, if I add them to the project as files and I access them through this method I created everything is fine (or using libraries like SDWebImage), but I believe I'm losing the power of app thinning as the images are hosted as files, so e.g. iPhone 7 will have both 2x and 3x resolutions when only 2x is needed.

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

}

So my question is, can anyone explain me the process to use HEIC as images hosted in the image assets folder and make it compatible with app thinning (just fetch the needed resources, i.e. 2x, 3x)?

UPDATE: After researching more I realised images are loaded from IB when I just set the image name on the image view. Do you know how this is internally working? which constructor is IB using to set the UIImage to the UIImageView?

UPDATE 2: I have submitted a radar to Apple: Radar

Navarino answered 23/3, 2018 at 12:35 Comment(7)
I haven’t heic image. Can you please share from where I can download it ?Lustring
You can not do this because assets does not support heic You can convert heic to JPG / PNG please read this devstreaming-cdn.apple.com/videos/wwdc/2017/511tj33587vdhds/511/…Dawnedawson
@Dawnedawson HEIC is supported by assets, see the apple documentationJaneyjangle
however, it is not compatible with UIImage and app thinningJaneyjangle
Daniel, do you know how IB works in terms of assigning the UIImage to the UIImageView outlet? Heic format works there from the asset folder but I don't know what's the internal mechanism to set the image in the UIImageViewNavarino
When I make an asset catalog containing HEIF files, the images do not physically seem to be stored in the asset catalog at all. I end up with an Assets.car file that is only 16 KB in size, and which contains only the empty trees and no actual data.Cainozoic
Really? In my case I see the same folder structure than with png, i.e. contents.json and the assets with HEIC formatNavarino
C
1

Apple's asset compiler re-encodes all images that come into it in a variety of internal formats, some standard and some proprietary, depending on a bunch of factors, including the type of image, the target OS version, and possibly other factors. Unfortunately, at the time of this writing, the asset compiler seems to be buggy as far as HEIC files are concerned; if I try to put an HEIC file into an asset catalog, it appears to be left out. The image data is not copied into the Assets.car file, which itself is only 16 KB in size, containing only a few empty B-trees. Therefore, when you try to load the image using UIImage, you get nothing.

Fortunately, since the asset compiler recodes all images fed into it anyway, you can just re-encode your images to another format (I recommend PNG, as it is lossless), and the resulting file that the end-user receives should be identical to what it would have been with the HEIF input file (and ironically, it might end up being coded as HEIF, since the assets format supports it). So that is what I would do until Apple fixes this bug in the asset compiler.

Cainozoic answered 4/4, 2018 at 1:8 Comment(6)
Are you sure about this? If you create the "New Image Set" and drag the HEIC image inside (1x, 2x or 3x) you'll see it within the asset folder, next to the contents.json file.Navarino
@Navarino In the source directory, yes. But have you looked in the compiled binary? When I do it, it's not in there.Cainozoic
I wrote Apple about this as "level coverage" and they told me I can use ImageIO framework to access HEIC images from the assets folder, but I don't know how to get the URL from the assets folder in order to use "CGImageSourceCreateWithURL". Any idea?Navarino
Definitely you are right, I tried several ways to add assets to the assets folder and the HEIC images are not included in the IPA.Navarino
@Navarino There is no folder for the assets in the IPA. All the images in the asset catalog are recoded and copied into a proprietary-format Assets.car file. Unfortunately HEIC files don't seem to make it in, and I'm about 99% sure it's a bug. So as a temporary workaround until that's fixed, you can either put recoded PNG files into the asset catalog, or you can take the images out of the asset catalog and just include them as plain old resources (and then get the URLs via the Bundle API).Cainozoic
Sorry, I meant Assets.car file. I opened and as you confirmed, HEIC images are not there. Somebody from Apple told me HEIC is relatively new for them and they might not support that yet. So I’ll keep going with the Radar. Will keep you updatedNavarino
N
0

After a big research through Radar and Apple DTS, I received the following answer from an engineer who contacted other engineering teams:

“Hi,

My email started a long email thread involving a number of engineers tracing your question through the system. Eventually, they found that HEIC format is not supported in image assets and in other parts of the system at this time where jpg and png files are presently used. Specifically, I am referring to automatically loaded resources such as those saved in storyboards or other Xcode generated resources and files. There is no workaround available at this time.

This does not mean that you cannot use HEIC images in your app. If you would like use an HEIC image in your code, then you can use Image I/O to load the image.

Please try again in future versions of the operating system.”

TL;DR:

It’s not possible to use HEIF on the assets folder yet. Maybe in the future.

UPDATE:

Tested on Xcode 10 beta 5 and now the Assets.car contains the HEIF images, which indicates it's possible to use HEIF images as part of the assets folder.

Navarino answered 20/4, 2018 at 18:52 Comment(0)
N
0
  • Xcode 15.0 Beta 5
  • iOS17.0
  • First Stpe:change the HEIF image file extension to .heif xxx.HEIC -> xxx.heif
  • Second Step: drag the file into the xcode project folder
  • Third Step: go to the project settings Build Phases- Copy Bundle Resources, add the xxx.heif file
  • Finally,I can read the image with CGImageSourceCreateWithData (use
    Bundle.main.path get path then NSData contentsOfFile).

Note that this may not be a best practice!

Nightmare answered 16/8, 2023 at 4:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.