#!/usr/bin/env perl use v5.36; use strict; use warnings; #use utf8; use Carp; use Convert::Color; use Term::ANSIScreen qw/:color/; use GD; use Data::Dumper; use Term::ReadKey; my ($cols, $rows, $wpixels, $hpixels) = GetTerminalSize(); # Prevent auto-wrapping $cols--; $rows--; # "Greyscale" unicode blocks # This could be specified nicer, but seems to be a problem when posting to PerlMonks, see comment below my @shades; foreach my $char (qw(32 9617 9618 9619 9608)) { my $tmp = chr($char); utf8::encode($tmp); push @shades, $tmp; } my @termcolors; # Pre-generate colors foreach my $termcolor (qw[red yellow green cyan blue magenta white]) { my $tmp = color $termcolor . ' on black'; push @termcolors, $tmp; } # Iterate through all image filenames given on command line foreach my $fname (@ARGV) { print "------ $fname ------\n"; my $ok = 0; eval { printImage($fname); $ok = 1; }; if(!$ok) { print STDERR "ERROR: $!\n"; } print "\n"; } sub printImage($fname) { my $img = GD::Image->new($fname); my ($origw, $origh) = $img->getBounds(); my ($w, $h) = ($origw + 0, $origh + 0); my $divfactor = 1; if($w > $cols) { my $tmp = $w / $cols; #print "$w / $cols / $tmp\n"; if($tmp > $divfactor) { $divfactor = $tmp; } } if($h > $rows) { my $tmp = $h / $rows; #print "$h / $rows / $tmp\n"; if($tmp > $divfactor) { $divfactor = $tmp; } } if($divfactor > 1) { $w = int($w / $divfactor); $h = int($h / $divfactor); my $newpic = GD::Image->new($w, $h, 1); $newpic->copyResized($img, 0, 0, # DEST X Y 0, 0, # SRC X Y $w, $h, # DEST W H $origw, $origh, # SRC W H ); $img = $newpic; } my $lastcindex = -1; for(my $y = 0; $y < $h; $y++) { for(my $x = 0; $x < $w; $x++) { my $index = $img->getPixel($x, $y); my ($r,$g,$b) = $img->rgb($index); #my $grey = int(($r + $g + $b) / 3); my $basecolor = Convert::Color->new('rgb8:' . join(',', $r, $g, $b)); my ($ph, $ps, $pv) = $basecolor->as_hsv->hsv; my $colormode = 0; if($ps > 0.5) { $colormode = 1; } # Map the brightness to the corresponding Unicode characters my $brightness = int($pv * 4); if(!defined($shades[$brightness])) { croak("Undefined $pv -> $brightness"); } my $shade = $shades[$brightness]; # Map the color to roughly their corresponding ANSI terminal color code. my $cindex = 0; if($ps < 0.5) { # White $cindex = 6; } elsif($ph > 34 && $ph <= 82) { # Yellow $cindex = 1; } elsif($ph > 82 && $ph <= 159) { # Green $cindex = 2; } elsif($ph > 159 && $ph <= 205) { # Cyan $cindex = 3; } elsif($ph > 205 && $ph <= 270) { # Blue $cindex = 4; } elsif($ph > 270 && $ph <= 330) { # Magenta $cindex = 5; } else { # Red $cindex = 0; } if($cindex != $lastcindex) { print $termcolors[$cindex]; $lastcindex = $cindex; } print $shade; } print "\n"; } { my $reset = color 'reset'; print $reset; } return; }