package Image::ASCII;
# by Nicholas Venturella
use strict;
use GD;
sub new ($$) {
my ($self, $path, $max, $text) = @_;
# Load image
my $image = GD::Image->new($path);
my ($x, $y) = $image->getBounds();
# Resize?
$max = 175 unless($max);
($image, $x, $y) = _imageResizeBicubic($image, $max) if ($x > $max || $y > $max);
# Deal with text
$text = '.:coCO8@' unless ($text);
my @text = split //, $text;
#@text = (@text, @text) while ($x*$y > scalar(@text));
# Begin HTML document
my ($R, $G, $B, $gray) = (0);
my $result = qq¤\r\n
\r\nBOT2K3 // Image To ASCII\r\n\r\n\r\n\r\n\r\n\r\n¤;
my $j; for ($j = 0; $j < $y; $j += 1) {
my $i; for ($i = 0; $i < $x; $i++) {
my $index = $image->getPixel($i, $j);
my ($r,$g,$b) = $image->rgb($index);
unless (($r == $R) and ($g == $G) and ($b == $B)) {
($R, $G, $B) = ($r, $g, $b);
$gray = ($r*.3 + $g*.59 + $b*.11);
my $color = '#' . sprintf("%.2X%.2X%.2X", $r, $g, $b);
$result .= qq¤¤;
}
my $which = int($gray * scalar(@text)/255);
if ($which >= scalar(@text)) { $which = scalar(@text) - 1; }
$result .= $text[$which];
}
$result .= "\n";
}
# End HTML document
$result .= qq¤ \r\n |
¤;
return $result;
}
sub _imageResizeBicubic {
my ($image, $max) = @_;
my ($x, $y) = $image->getBounds();
my $r = ($x > $y) ? ($x/$max) : ($y/$max);
my $thumb = _imageCopyResampleBicubic($image, 0, 0, 0, 0, int($x/$r), int($y/$r), $x, $y);
return $thumb, int($x/$r), int($y/$r);
}
sub _imageCopyResampleBicubic {
my ($src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = @_;
my $dst_img = GD::Image->new($dst_w, $dst_h, 1);
my $scaleX = ($src_w - 1) / $dst_w;
my $scaleY = ($src_h - 1) / $dst_h;
my $scaleX2 = $scaleX / 2;
my $scaleY2 = $scaleY / 2;
my $tc = $src_img->isTrueColor();
for (my $y = $src_y; $y < $src_y + $dst_h; $y++) {
my $sY = $y * $scaleY;
my $siY = int($sY);
my $siY2 = int($sY + $scaleY2);
for (my $x = $src_x; $x < $src_x + $dst_w; $x++) {
my $sX = $x * $scaleX;
my $siX = int($sX);
my $siX2 = int($sX + $scaleX2);
if ($tc) {
my $c1 = $src_img->getPixel($siX, $siY2);
my $c2 = $src_img->getPixel($siX, $siY);
my $c3 = $src_img->getPixel($siX2, $siY2);
my $c4 = $src_img->getPixel($siX2, $siY);
my $r = (($c1 + $c2 + $c3 + $c4) >> 2) & 0xFF0000;
my $g = ((($c1 & 0xFF00) + ($c2 & 0xFF00) + ($c3 & 0xFF00) + ($c4 & 0xFF00)) >> 2) & 0xFF00;
my $b = ((($c1 & 0xFF) + ($c2 & 0xFF) + ($c3 & 0xFF) + ($c4 & 0xFF)) >> 2);
$dst_img->setPixel($dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
} else {
my @c1 = $src_img->rgb($src_img->getPixel($siX, $siY2));
my @c2 = $src_img->rgb($src_img->getPixel($siX, $siY));
my @c3 = $src_img->rgb($src_img->getPixel($siX2, $siY2));
my @c4 = $src_img->rgb($src_img->getPixel($siX2, $siY));
my $r = ($c1[0] + $c2[0] + $c3[0] + $c4[0])/4;
my $g = ($c1[1] + $c2[1] + $c3[1] + $c4[1])/4;
my $b = ($c1[2] + $c2[2] + $c3[2] + $c4[2])/4;
$dst_img->setPixel($dst_x + $x - $src_x, $dst_y + $y - $src_y, ($r << 16)|($g << 8)|$b);
}
}
}
return $dst_img;
}
1;