Fix libvips color extraction when multiple maxima differ only on blue component (#30632)

This commit is contained in:
Claire 2024-06-11 15:58:10 +02:00 committed by GitHub
parent f48f39a767
commit 328d3a87f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 12 deletions

View File

@ -122,27 +122,29 @@ module Paperclip
colors['out_array'].zip(colors['x_array'], colors['y_array']).map do |v, x, y| colors['out_array'].zip(colors['x_array'], colors['y_array']).map do |v, x, y|
rgb_from_xyv(histogram, x, y, v) rgb_from_xyv(histogram, x, y, v)
end.reverse end.flatten.reverse.uniq
end end
# rubocop:disable Naming/MethodParameterName # rubocop:disable Naming/MethodParameterName
def rgb_from_xyv(image, x, y, v) def rgb_from_xyv(image, x, y, v)
pixel = image.getpoint(x, y) pixel = image.getpoint(x, y)
# Unfortunately, we only have the first 2 dimensions, so try to # As we only have the first 2 dimensions for this maximum, we
# guess the third one by looking up the value # can't distinguish with different maxima with the same `r` and `g`
# values but different `b` values.
#
# Therefore, we return an array of maxima, which is always non-empty,
# but may contain multiple colors with the same values.
# NOTE: this means that if multiple bins with the same `r` and `g` pixel.filter_map.with_index do |pv, z|
# components have the same number of occurrences, we will always return next if pv != v
# the one with the lowest `b` value. This means that in case of a tie,
# we will return the same color twice and skip the ones it tied with.
z = pixel.find_index(v)
r = (x + 0.5) * 256 / BINS r = (x + 0.5) * 256 / BINS
g = (y + 0.5) * 256 / BINS g = (y + 0.5) * 256 / BINS
b = (z + 0.5) * 256 / BINS b = (z + 0.5) * 256 / BINS
ColorDiff::Color::RGB.new(r, g, b) ColorDiff::Color::RGB.new(r, g, b)
end end
end
def w3c_contrast(color1, color2) def w3c_contrast(color1, color2)
luminance1 = (color1.to_xyz.y * 0.01) + 0.05 luminance1 = (color1.to_xyz.y * 0.01) + 0.05