Francois Gouget : winetest/build-patterns: Use the Luv colorspace for interpolating colors.

Alexandre Julliard julliard at winehq.org
Tue Aug 31 15:39:30 CDT 2021


Module: tools
Branch: master
Commit: d6b3ff7f6fa99544dae245155ef3a0d9bac2c365
URL:    https://source.winehq.org/git/tools.git/?a=commit;h=d6b3ff7f6fa99544dae245155ef3a0d9bac2c365

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Tue Aug 31 15:40:02 2021 +0200

winetest/build-patterns: Use the Luv colorspace for interpolating colors.

Interpolation works best in a colorspace where the distance between
colors is representative of their perceptual difference. That's
roughly the case in the Luv colorspace and much less so in the RGB
one.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 winetest/build-patterns | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/winetest/build-patterns b/winetest/build-patterns
index ff72516..7229140 100755
--- a/winetest/build-patterns
+++ b/winetest/build-patterns
@@ -22,6 +22,7 @@ use open ':utf8';
 use CGI qw(:standard);
 use POSIX; # ceil()
 
+use Graphics::ColorObject;
 use Text::CSV::Encoded;
 use Time::Piece;
 
@@ -860,15 +861,15 @@ if (open(my $fh, "-|", $cmd))
 sub color2html($)
 {
     my ($c) = @_;
-    return sprintf "#%02x%02x%02x", $c->[0], $c->[1], $c->[2];
+    return "#". $c->as_RGBhex();
 }
 
-sub blend($$$)
+sub interpolate($$$)
 {
     my ($p, $start, $end) = @_;
-    my $r = [int($start->[0] * (1 - $p) + $end->[0] * $p + 0.5),
-             int($start->[1] * (1 - $p) + $end->[1] * $p + 0.5),
-             int($start->[2] * (1 - $p) + $end->[2] * $p + 0.5)];
+    my $r = [$start->[0] * (1 - $p) + $end->[0] * $p,
+             $start->[1] * (1 - $p) + $end->[1] * $p,
+             $start->[2] * (1 - $p) + $end->[2] * $p];
     return $r;
 }
 
@@ -896,7 +897,7 @@ sub compute_set_colors($)
     my $count = @values;
     if ($count == 1)
     {
-        $set->{$values[0]} = color2html($keycolors[0]);
+        $set->{$values[0]} = color2html(Graphics::ColorObject->new_RGB255($keycolors[0]));
     }
     else
     {
@@ -904,6 +905,12 @@ sub compute_set_colors($)
         # when many colors are needed.
         $keycolors[0] = [0, 179, 179] if ($count > 10);
 
+        # Convert the key colors to the Luv colorspace where the distance
+        # between colors is roughly representative of the perceptual difference
+        # between them. This allows linear interpolation to produce relatively
+        # uniform gradients (which is not the case in the RGB colorspace).
+        map { $_ = Graphics::ColorObject->new_RGB255($_)->as_Luv() } @keycolors;
+
         # Compute the total length of the path traced by the key colors through
         # the colorspace. This is necessary so the gradient remains uniform
         # even if two key colors are close to each other. This does assume that
@@ -929,8 +936,8 @@ sub compute_set_colors($)
             }
 
             # And blend
-            my $Rgb = blend(($pos - $keypos[$k]) / ($keypos[$k+1] - $keypos[$k]), $keycolors[$k], $keycolors[$k+1]);
-            $set->{$values[$_]} = color2html($Rgb);
+            my $Luv = interpolate(($pos - $keypos[$k]) / ($keypos[$k+1] - $keypos[$k]), $keycolors[$k], $keycolors[$k+1]);
+            $set->{$values[$_]} = color2html(Graphics::ColorObject->new_Luv($Luv));
         }
     }
 }




More information about the wine-cvs mailing list