sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Enhancement: add option to allow hue modulatation in non-linear colourspace to match CSS filter hue-rotate

Open asttapenko opened this issue 3 years ago • 3 comments

What are you trying to achieve?

sharp's modulate() uses LCH convert (as mentioned here), therefore result of modulate({ hue: 180}) is differs from CSS-filter hue-rotate(180deg)

When you searched for similar issues, what did you find that might be related?

Not found any related issues or solutions.

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

Result with sharp modulate({ hue: 180}) image Result with cssgenerator image

Image data:

{
  format: 'jpeg',
  size: 23572,
  width: 400,
  height: 268,
  space: 'srgb',
  channels: 3,
  depth: 'uchar',
  density: 72,
  chromaSubsampling: '4:2:0',
  isProgressive: false,
  resolutionUnit: 'inch',
  hasProfile: false,
  hasAlpha: false,
  orientation: 1
}

Is there any solution to make them the same? Thank you

asttapenko avatar Apr 20 '22 10:04 asttapenko

I'd need to check their source code but I suspect most web browsers probably use the HSL colourspace for this calculation, which is usually less accurate than LCH, so you might be seeing the effects of rounding errors or clipping when applying such a filter in a browser.

There's some discussion about this at https://github.com/libvips/libvips/discussions/2486

I guess we could add optional support to modulate for the use of HSV instead of LCH to match less accurate software, but this would need to implement the angle calculations for hue. Happy to accept a PR, if you're able.

lovell avatar Apr 20 '22 11:04 lovell

Another point worth mentioning about these colourspaces is that LCH is linear whereas HSL is non-linear, so it's a bit like comparing linear RGB with non-linear sRGB. This detail provides a suitable name for the future possible future option to control this, e.g. specify { linear: false } to switch to HSL-based hue rotation.

lovell avatar Apr 21 '22 19:04 lovell

Not sure I'm able to provide a good PR, but I have made hue-rotate with this matrix via recomb(). It's not 100% exact, but gives colors very close to CSS-filter hue-rotate()

asttapenko avatar Apr 25 '22 11:04 asttapenko