It also needs a binmode to prevent Unicode warnings. It is fun to play with. Here is a bit of a cleaned up version that uses Unicode, map, say and ternary. It also resets the color at the end of each line: not all peple prefer a black background.
#!/usr/bin/perl use 5.036001; use warnings; our $VERSION = "0.01 - 20230629"; our $CMD = $0 =~ s{.*/}{}r; sub usage { my $err = shift and select STDERR; say "usage: $CMD ..."; exit $err; } # usage use Carp; use Convert::Color; use Term::ANSIScreen qw(:color); use GD; use Data::Peek; use Term::ReadKey; use Getopt::Long qw(:config bundling); GetOptions ( "help|?" => sub { usage (0); }, "V|version" => sub { say "$CMD [$VERSION]"; exit 0 +; }, "d|dark". "|dark-background!" => \ my $dark, "v|verbose:1" => \(my $opt_v = 0), ) or usage (1); my $bgc = $dark ? "black" : "white"; my ($cols, $rows, $wpixels, $hpixels) = GetTerminalSize (); # Prevent auto-wrapping $cols--; $rows--; # "Greyscale" unicode blocks binmode STDOUT, ":encoding(utf-8)"; # This could be specified nicer, but seems to be a problem when postin +g to PerlMonks, see comment below my @shades = ("\N{SPACE}", "\N{LIGHT SHADE}", "\N{MEDIUM SHADE}", "\N{ +DARK SHADE}", "\N{FULL BLOCK}"); # Pre-generate colors my @termcolors = map { color $termcolor . " on $bgc" } qw( red yellow green cyan blue magenta white ); # White won't "wor +k" on light background # Iterate through all image filenames given on command line foreach my $fname (@ARGV) { say "------ $fname ------"; my $ok = 0; eval { printImage ($fname); $ok = 1; }; $ok ? say "" : warn "ERROR: ", $! ? "$!" : $@, "\n"; } sub printImage ($fname) { -s $fname or croak ("Non-existing or empty image"); my $img = GD::Image->new ($fname) or croak "GD::Image cannot proce +ss $fname"; my ($origw, $origh) = $img->getBounds (); my ($w, $h) = ($origw + 0, $origh + 0); my $reset = color "reset"; my $divfactor = 1; if ($w > $cols) { my $tmp = $w / $cols; #say "$w / $cols / $tmp"; $tmp > $divfactor and $divfactor = $tmp; } if ($h > $rows) { my $tmp = $h / $rows; #say "$h / $rows / $tmp"; $tmp > $divfactor and $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; } for (my $y = 0; $y < $h; $y++) { my $lastcindex = -1; 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 = $ps > 0.5 ? 1 : 0; # Map the brightness to the corresponding Unicode characte +rs my $brightness = int ($pv * 4); defined ($shades[$brightness]) or croak ("Undefined $pv -> $brightness"); my $shade = $shades[$brightness]; # Map the color to roughly their corresponding ANSI termin +al color code. my $cindex = $ps < 0.5 ? 6 : # White $ph > 34 && $ph <= 82 ? 1 : # Yellow $ph > 82 && $ph <= 159 ? 2 : # Green $ph > 159 && $ph <= 205 ? 3 : # Cyan $ph > 205 && $ph <= 270 ? 4 : # Blue $ph > 270 && $ph <= 330 ? 5 : # Magenta 0 ; # Red unless ($cindex == $lastcindex) { print $termcolors[$cindex]; $lastcindex = $cindex; } print $shade; } say $reset; } print $reset; return; } # printImage
In reply to Re: Imagecat - show color images in a terminal
by Tux
in thread Imagecat - show color images in a terminal
by cavac
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |