lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
28.96k stars 1.29k forks source link

Metadata: expose `chromaSubsampling` for AVIF #3584

Open tats-u opened 1 year ago

tats-u commented 1 year ago

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

  System:
    OS: Windows 10 10.0.22621
    CPU: (8) x64 Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
    Memory: 11.85 GB / 31.68 GB
  Binaries:
    Node: 18.14.0 - ~\scoop\apps\volta\current\appdata\tools\image\node\18.14.0\node.EXE
    Yarn: 1.22.19 - ~\scoop\apps\volta\current\appdata\tools\image\yarn\1.22.19\bin\yarn.CMD
    npm: 9.3.1 - ~\scoop\apps\volta\current\appdata\tools\image\node\18.14.0\npm.CMD
  npmPackages:
    sharp: ^0.31.3 => 0.31.3

What are the steps to reproduce?

What is the expected behaviour?

await sharp("./image.avif").metadata()
await sharp("./lossy.webp").metadata()

should include chromaSubsampling field like JPEG. That of Lossy WebPs is always "4:2:0". Most AVIF use YUV (4:2:0 or 4:4:4).

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

import sharp from "sharp";
import YAML from "yaml";

/**
 * @param type {string}
 * @param img {import("sharp").Sharp}
 */

async function printMeta(type, img) {
  const { icc: _icc, iptc: _iptc, ...meta } = await img.metadata();

  console.log(`${type} meta:\n\n${YAML.stringify(meta)}`);
}

await printMeta("AVIF", sharp("./avif.avif"));
await printMeta("WebP", sharp("./webp.webp"));

Please provide sample image(s) that help explain this problem

lovell commented 1 year ago

For AVIF, libheif exposes subsampling metadata via get_image_chroma_from_configuration but we'd need to add support for this to libvips first. There might be some complexity around different chroma subsampling for alpha vs non-alpha channels.

A libvips PR to expose this would be welcome, if you're able.

For WebP, libwebp does not expose metadata about whether subsampling (a.k.a. "sharp_yuv") was used at compression time, so there's not a lot we can do here (I suspect it will be buried somewhere in the compressed bitstream).

tats-u commented 1 year ago

we'd need to add support for this to libvips first.

I see.

For WebP, libwebp does not expose metadata about whether subsampling (a.k.a. "sharp_yuv") was used at compression time

4:2:0 for ALL lossy WebP whether sharp YUV is used or not unlike JPEG or AVIF. Lossless ones use a different algorithm.