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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With