-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Color tint feature not working as expected #1235
Comments
|
So after some more digging into the source it would appear that the issue is related to the LAB colour space usage. sharp uses the color module to retrieve the darkness In colour.js
In operations.cc change the luminance colour space to LCH:
Rebuild sharp:
Result for colour {r: 0, g: 246, b: 255} (Cyan) |
Thank you for reporting this @wezside and great detective work on what's causing it. @jcupitt What are the valid ranges for the AB chroma values of LAB in libvips? The docs currently say "bands have the obvious range" and I'm sure you've probably told me before but I can't remember and can't find them mentioned in previous libvips issues. |
No problem. Great library. It's worth pointing out that my "fix" still has some issues in outer ranges (like 350 degree hue). I had one tint colour |
Hello, float LAB is 0-100 for L and +/- 128 for ab. I guess I'll try a small example. |
Here's a simple tint in Ruby: #!/usr/bin/env ruby
require 'vips'
colour = [255, 0, 0]
image = Vips::Image.new_from_file ARGV[0]
image = image.colourspace "b-w"
lut = Vips::Image.identity
lut = (lut / 256) * colour
lut = lut.cast "uchar"
image = image.maplut lut
image.write_to_file ARGV[1] That'll do an 8-bit image, you'd need to change the 256 and the identity for a 16-bit one. |
I see sharp is going to LAB, keeping L and setting a constant value for ab. I remember experimenting with this: it doesn't work that well, unfortunately, since people expect saturation to scale with luminance, but constant ab will give you saturated dark colours and washed out bright ones (relatively). Here's another tint. This one makes a gradient between any two colours in CIELAB and maps black-white in the original to that. #!/usr/bin/env ruby
require 'vips'
# make a lut which is a smooth gradient from start colour to stop colour, with
# start and stop in CIELAB
def gradient(start, stop)
lut = Vips::Image.identity / 255
lut = lut * stop + (lut * -1 + 1) * start
lut.colourspace(:srgb, source_space: :lab)
end
# various colours as CIELAB triples
black = [0, 0, 0]
red = [53, 80, 67]
green = [88, -86, 83]
blue = [32, 79, -108]
white = [100, 0, 0]
image = Vips::Image.new_from_file ARGV[0]
image = image.colourspace("b-w").maplut(gradient black, red)
image.write_to_file ARGV[1] Sample output: |
(the odd |
Brilliant, thanks @jcupitt, I'll try your first example as that looks perfectly suitable and should be a bit simpler/faster than a (L)AB conversion. |
Add test cases for more tint colours and input interpretations
On closer inspection it turns out there were a couple of bugs in the current implementation where negative AB values would be ignored and LAB interpretation was sometimes lost. Commit 54a71fc addresses these and adds new test cases that would have caught this problem. This fix will be in v0.20.3 - thanks again for reporting @wezside and thanks as always for your help @jcupitt. |
v0.20.3 now available. |
If I use the following code I would expect three tinted images, a red tint, green tint, blue tint. Here is what the code produces:
The text was updated successfully, but these errors were encountered: