1 package Shiar_Sheet::Colour;
5 use List::Util qw( min max );
9 # ITU-R recommendation 601 luma co-efficients
12 our $kg = 1 - $kb - $kr;
14 my $PI = 2 * atan2 1, 0;
18 my @rgb = @_ >= 3 ? @_ : (map {hex} $_[0] =~ /(..)/g);
23 # convert from YPbPr values -1..1
25 my ($y, $cb, $cr) = @_;
27 my @rgb = map { max(0, min(255, $_ * 255)) } (
29 $y - $cb * (1 - $kb) * $kb/$kg - $cr * $kr/$kg,
30 $y + $cb * (1 - $kb) ,
36 # convert from YPbPr values 0..255 (or hex string)
38 my ($y, $cb, $cr) = @_ >= 3 ? @_ : (map {hex} $_[0] =~ /(..)/g);
40 $_ -= 128 for $cb, $cr;
41 $_ /= 255 for $y, $cb, $cr;
43 $class->newyuv($y, $cb, $cr);
47 # perceived brightness
48 my ($r, $g, $b) = @{ $_[0] };
49 return $r*$kr + $g*$kg + $b*$kb;
53 # colour shift (red = 0 .. 1)
54 my ($r, $g, $b) = @{ $_[0] };
55 my $hue = atan2 sqrt(3) * ($g - $b), $r*2 - $g - $b;
56 $hue /= $PI * 2; # -.5 .. .5
57 $hue++ if $hue < 0; # fp $hue %= 1
64 return $rgb->hue, abs(min(@{$rgb}) - $v), $v;
69 $str .= sprintf '%X', min($_ / 17 + .5, 15) for @{ $_[0] };
75 $str .= sprintf '%02X', $_ for @{ $_[0] };