# Inspecting Convert::Color POD sample values deeply
use Data::Dump qw/dd/;
my $red = Convert::Color::HSL->new( 0, 1, 0.5 );
# Can also parse strings say q(pink); my $pink = Convert::Color::HSL->new( '0,1,0.8' ); dd $pink; dd $pink->as_rgb; dd $pink->as_rgb->as_hsl;
my $cyan = Convert::Color->new( 'hsl:300,1,0.5' );
say q(cyan); dd $cyan; dd $cyan->as_rgb;
say "132"; my $onethreetwo= Convert::Color::RGB->new(map {(_five_to_1($_))} (1, 3, 2)); dd $onethreetwo; dd $onethreetwo->as_hsl->hsl; dd $onethreetwo->as_hsl->chroma;
1 #! perl 2 # Show Term::ANSIColor 216-cube of colors 000..555 arrayed as HSL grid 3 # 4 # Copyright 2019 William Ricker modifying code by Andy Lester 5 # License Same As Perl 6 7 8 use Modern::Perl 2017; 9 10 use Convert::Color; 11 use Convert::Color::HSL; 12 use Convert::Color::RGB; 13 14 use Term::ANSIColor; 15 16 use Readonly; 17 # use Data::Dump qw/dd/; # needed in commented out traces 18 19 my Readonly $degrees = 12; ## This is the number that avoids collisions 20 my Readonly $columns = 360 / $degrees; 21 22 23 my $where_href = _save_rgb_grid(); 24 _show_hue_sat_grid(1, 0, $where_href); 25 _show_hue_sat_grid(0, 0, $where_href); 26 # _show_hue_sat_grid(0, 1, $where_href); # 1 for Skip ; leave the sparse matrix gaps blank 27 28 29 ############ SUBROUTINES ########### 30 31 32 # Helper to scale Term::ANSIColor 0..5 R,G,B to 0.0 .. 1.0 standard 33 sub _five_to_1{ 34 return shift()/5; 35 } 36 37 # our %Where; 38 39 40 sub _where { 41 # pass in HSL object, returns xyz grid to display it on 42 # if $degrees selected properly, won't cause collisions 43 my $hsl = shift; 44 my ($h, $s, $l) = $hsl->hsl; 45 my $c = $hsl->chroma; 46 my $y = int 10*$l ; 47 my $z = int 10*$s ; 48 my $x = sprintf "%0d", ($degrees * int( ($h+($degrees/2))/$degrees )); 49 return [ $x, $y, $z] ; 50 } 51 52 53 ## HSL "Grid" 54 55 # show Hue Sat Lum grid 56 # Modeled on Ack3 _show_rgb_grid, but with HSL iteration over sparce save matrix 57 # If a position is blank, repeat previous color 58 # 59 # 60 # Because 20 columns wide, 61 # omits 'rgb' prefix 62 # stacks text over background 63 # 64 # arguments 65 # Reversed = 1 | 0 66 # Skip : true will not repeat values but leave blank space 67 # Where = the hashref returned by sibling 68 # 69 # 70 sub _show_hue_sat_grid { 71 my ($reversed, $skip, $where ) = @_; 72 die unless 'HASH' eq ref $where; 73 my (%Where) = ($where->%*); 74 75 my @Hues = map { $degrees * $_ } 0 .. ($columns-1); 76 say "ddd=Hue Degrees"; 77 say join( q( ), map { sprintf "%03d",$_ } @Hues), 78 " l s"; 79 for my $z (sort {$b <=> $a} keys %Where){ 80 # say "s $z" ; # dd $Where{$z}; 81 for my $y (sort {$b <=> $a} keys $Where{$z}->%*){ 82 # say "l $y"; # dd $Where{$z}->{$y}; 83 my $code='rgb000'; # default if hue=0 ever missing 84 for my $x (@Hues) { 85 86 my $skippable; 87 if ( defined $Where{$z}->{$y}->{$x}) { 88 my $i = 0; 89 90 # a few tight hue angles get 324 336 so pick other one in Reversed 91 $i=1 if ($reversed > 0 and 1 < scalar $Where{$z}->{$y}->{$x}->@*); 92 # if ( 1 < scalar $Where{$z}->{$y}->{$x}->@*){ dd $Where{$z}->{$y};}; 93 94 $code = $Where{$z}->{$y}->{$x}->[0]->{code} // $code; ## repeat if position not used 95 } 96 else { 97 $skippable=1; 98 } 99 100 if ($skip and $skippable) { 101 print q( ); 102 } 103 else { 104 print( ($reversed ? Term::ANSIColor::colored( substr($code,3,3), $code ) 105 : Term::ANSIColor::colored( substr($code,3,3), "reverse $code" ) 106 ), 107 ' ') ; 108 } 109 } 110 say "$y $z"; 111 } 112 say ""; 113 } 114 115 } 116 117 118 # Save the RGB Grid values into HSL grid 119 # This saves a sparse matrix in nested hash form 120 # 121 # Modeled on Ack3 _show_rgb_grid, but with HSL and save instead of print 122 # saves into %Where for sibling 123 sub _save_rgb_grid { 124 # Optional statistics 125 # my (%Hues,%Lums,%Sats); 126 my %Where; 127 for my $r ( 0 .. 5 ) { 128 for my $g ( 0 .. 5 ) { 129 for my $b ( 0 ..5 ) { 130 131 my $rgb = "$r$g$b"; 132 my $code = "rgb$r$g$b"; 133 my $hsl = Convert::Color::RGB->new(map {(_five_to_1($_))} ($r, $g, $b))->as_hsl; 134 my @HSL = ($hsl->hsl); 135 # Optional collect stats 136 # my { ($h,$s,$l)=@HSL; $Hues{int $h+0.5}++; $Lums{$l}++; $Sats{$s}++; } 137 my $hsl_code = sprintf q(h:%3d,s:%4.2f,l:%4.2f), @HSL; 138 my ($x,$y, $z) = _where($hsl)->@*; 139 # warn "Mapping white to [$x,$y, $z]" if 5==$r and 5==$g and 5==$b; 140 # warn "[$x,$y] conflict #{[$Where{$y}->{$x}]} = $code (h=$HSL[0])" 141 # if defined $Where{$y}->{$x} ; 142 push $Where{$z}->{$y}->{$x}->@* , { code => $code, hsl=> $hsl } ; 143 144 } 145 } 146 } 147 148 # say "Hues"; for my $k (sort {$a <=> $b} keys %Hues){ say "$Hues{$k}\t$k"; } 149 # say "Lums"; for my $k (sort {$a <=> $b} keys %Lums){ say "$Lums{$k}\t$k"; } 150 # say "Sats"; for my $k (sort {$a <=> $b}keys %Sats){ say "$Sats{$k}\t$k"; } 151 return \%Where; 152 } 153 154 155
184