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;