Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HEIC images within the assets folder not loaded

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

like image 979
jomafer Avatar asked Mar 23 '18 12:03

jomafer


1 Answers

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.

like image 153
Charles Srstka Avatar answered Nov 04 '22 14:11

Charles Srstka