strukturag / libheif

libheif is an HEIF and AVIF file format decoder and encoder.
Other
1.75k stars 303 forks source link

Strange color in Preview.app on macOS #95

Open hguandl opened 5 years ago

hguandl commented 5 years ago

I've tried to use libheif to encode pictures to heif. But I found that when I open the encoded pictures in Preview.app, the color becomes unexpected, which looks like the contrast is wrong.

pic1 (left: origin, right: encoded with libheif)

I think macOS uses Apple's own CoreImage to deal with heif. I also tried to encode the jpg file with Preview.app and it worked fine.

pic2 (left: origin, right: encoded with CoreImage)

After that, I converted these two heic images back to png with libheif. Both of them looked normal without any color problems.

So I have a temporary conclusion like this:

Encoder libheif (heif-convert) CoreImage (Preview.app)
libheif (heif-enc) YES NO (pic1)
CoreImage (Preview.app) YES YES (pic2)

We can never know how CoreImage decodes the image. But could we get any ideas from the picture it encoded?

Here are the original picture and ones encoded with two libraries: example.tar.gz

dreampiggy commented 5 years ago

I can reproduce this issue using my HEIF decoder/encoder SDWebImageHEIFCoder, which behave the same for all 4 Apple platforms (iOS/macOS/tvOS/watchOS)...It looks like a color overexposure :)

image

farindk commented 5 years ago

The CoreImage generated HEIF file contains a color-profile:

| Box: iprp ----- | size: 3395 (header size: 8) | | Box: ipco ----- | | size: 3330 (header size: 8) | | | Box: colr ----- | | | size: 3156 (header size: 8) | | | colour_type: prof | | | profile size: 3144

Looks like an sRGB profile. The libheif-generated image does not contain any color profile. Seems like Preview.app then interprets the RGB values differently.

One can add a color profile to the libheif generated images with the function heif_image_set_raw_color_profile(), but the heif_enc example does not do that currently when the input JPEG does not have one.

We could try whether it makes a difference to add a standard sRGB profile when we are converting from JPEG without profile.

dreampiggy commented 5 years ago

@farindk Is the latest version 1.4.0 still does not auto-apply a sRGB color profile ?

If so, in my user application level, (provide feature for iOS/macOS HEIF encoder) can apply a sRGB color profile during encoding a bitmap image.

I'm not quite famaliar with HEIF spec. Does there anything like WebP's color profile defaults to sRGB rule ? WebP Spec

Color Profile: Chunk Size bytes ICC profile. This chunk MUST appear before the image data.

There SHOULD be at most one such chunk. If there are more such chunks, readers MAY ignore all except the first one. See the ICC Specification for details.

If this chunk is not present, sRGB SHOULD be assumed.

fancycode commented 5 years ago

@farindk is this something we can do now with the latest color conversion improvements?

farindk commented 5 years ago

@dreampiggy: I thought that the default would be sRGB, but looking at the standards again, I cannot find anything about it. Since iOS usually uses the 'P3' space, it might be that Apple is using this as a default. Including an sRGB profile in each image might hence be a good idea.

Since there seem to be different sRGB ICC profiles floating around (from ~4 kB to ~60 kB), I am a bit hesitant to just add a random one by default.