Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

heif-enc output is 4x bigger than equivalent macOS Finder output #1266

Open
trevor-e opened this issue Aug 12, 2024 · 9 comments
Open

heif-enc output is 4x bigger than equivalent macOS Finder output #1266

trevor-e opened this issue Aug 12, 2024 · 9 comments

Comments

@trevor-e
Copy link

Hello,

This is related to an issue I opened in another project (lovell/sharp#4182) but seemed more relevant here since I'm able to reproduce this with heif-enc.

Basically, I'm trying to convert PNG images to HEIC and am finding the output to be much bigger than expected. For example, testing this command: heif-enc -q 85 -C average input.png -o output.heic produces a 736KB HEIC. However, if I take the same input image in Apple's Finder tool with 85 quality and export to HEIC, the result is much smaller at 168KB. This is a pretty drastic difference in compression size.

I've zipped and included all the images I'm testing with.
Archive.zip

@farindk
Copy link
Contributor

farindk commented Aug 12, 2024

The quality settings are not comparable. 85 in libheif is not 85 in macOS. You need to find a compression setting that gives comparable output quality. That depends a lot on the encoder plugin used.

@trevor-e
Copy link
Author

Thanks for the response. I believe I've been using libde265 for encoding, although looking at that project description now I'm not so sure since it only mentions decoding.

If you have any sensible defaults you can share for this that would be greatly appreciated, otherwise I will do some tinkering. Having the default file size generated by this tool be much smaller would be a great win.

@trevor-e
Copy link
Author

Attempting to figure out my exact encoder being used:

➜  heic-test git:(master) ✗ heif-enc --list-encoders
HEIC encoders:
- x265 = x265 HEVC encoder (3.5+1-f0c1022b6) [default]
AVIF encoders:
- aom = AOMedia Project AV1 Encoder 3.9.1 [default]
VVIC encoders:
JPEG encoders:
JPEG 2000 encoders:
HT-J2K encoders:

@farindk
Copy link
Contributor

farindk commented Aug 12, 2024

libde265 is the decoder. You are probably using the x265 encoder.

@trevor-e
Copy link
Author

trevor-e commented Aug 12, 2024

Some interesting findings for anyone new to this world like me:

➜  heic-test git:(master) ✗ otool -L /opt/homebrew/bin/heif-enc
/opt/homebrew/bin/heif-enc:
	@rpath/libheif.1.dylib (compatibility version 17.0.0, current version 1.18.1)
	/opt/homebrew/opt/jpeg-turbo/lib/libjpeg.8.dylib (compatibility version 8.0.0, current version 8.3.2)
	/opt/homebrew/opt/libpng/lib/libpng16.16.dylib (compatibility version 60.0.0, current version 60.0.0)
	/opt/homebrew/opt/libtiff/lib/libtiff.6.dylib (compatibility version 7.0.0, current version 7.2.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.12)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1700.255.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.100.2)
	
➜  heic-test git:(master) ✗ otool -L /opt/homebrew/lib/libheif.1.dylib
/opt/homebrew/lib/libheif.1.dylib:
	/opt/homebrew/opt/libheif/lib/libheif.1.dylib (compatibility version 17.0.0, current version 1.18.1)
	/opt/homebrew/opt/x265/lib/libx265.209.dylib (compatibility version 209.0.0, current version 209.0.0)
	/opt/homebrew/opt/libde265/lib/libde265.0.dylib (compatibility version 2.0.0, current version 2.8.0)
	/opt/homebrew/opt/aom/lib/libaom.3.dylib (compatibility version 3.0.0, current version 3.9.1)
	/opt/homebrew/opt/webp/lib/libsharpyuv.0.dylib (compatibility version 2.0.0, current version 2.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1700.255.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.100.2)

➜  heic-test git:(master) ✗ x265 --version
x265 [info]: HEVC encoder version 3.5+1-f0c1022b6

So I am using x265 as you suggested. Looking through the x265 options, an obvious one stood out to me:

heif-enc input.png -o output.heic -p preset=slow

simply setting it to use a slow performance preset gave me an image that's only 123KB, already smaller than Finder, and visually looks OK to me. Although interestingly if I set the -q 85 flag it doesn't seem to work and goes back to the 743KB size.

@silverbacknet
Copy link

That would be because the default x265 quality is 50. (Which maps to crf 25 in x265 itself.) Which may or may not be similar to Apple's quality 85 or 80 or whatever gets it to the same size, you'd have to actually view the file to figure that out.

The default x265 preset is already "slow". All you did was accidentally change the q.

(Side note: Apple will always be faster than libheif, at least for heic itself, since it's using hardware encoding on the Mx chip to do it instead of software.)

@trevor-e
Copy link
Author

trevor-e commented Aug 12, 2024

Thanks, you're right about that 🤦, although the x265 docs appear to be wrong:

-p/--preset <string>             Trade off performance for compression efficiency. Default medium

edit: oh you mean the libheif default for x265's preset

@silverbacknet
Copy link

That's x265's default, libheif sets its own defaults. OK, I admit it was confusing the way I put it, I should have said x265 plugin.

@lovell
Copy link
Contributor

lovell commented Aug 13, 2024

There may be some additional confusion here around controlling "how much CPU effort" an encoder should use. Many/most of libheif's encoders provide an integral speed parameter mapped to a relevant setting of their underlying library, however the x265 encoder differs slightly by providing a string-based preset parameter.

When encoding images via libheif, libvips currently exposes control over speed only (named effort to ensure consistency across all encoders, not just HEIF-based) and assumes that libheif will map speed onto something sensible. Is this still the right approach?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants