#! /usr/local/bin/perl use GD; # Fruit # By Duncan Martin - www.codebunny.org # No warranty or fitness for purpose guarentees. # Reuse freely, but give credit # Fruit takes a text file and a PNG and makes another PNG # format is # fruit.pl textfile inputimage outputimage [red,green,blue] # choose your font here # options are : Small, Large, MediumBold, Tiny, Giant $font = GD::Font->Small; # check number of arguments my $argc = @ARGV; if (($argc != 3) && ($argc != 4)) { print "Format is :\n fruit.pl textfile inputimage outputimage [red,green,blue]\n\n"; exit 1; } # store the arguments into more memorable names ($textFileName,$inputImageName,$outputImageName,$backgroundColours) = @ARGV; # load the text file into memory my $allText = ""; open TEXT,$textFileName or die "Couldn't open $textFileName"; while () { # replace carriage returns, line feeds and tabs with a single white space s/\n/ /go; s/\r/ /go; s/\t/ /go; # turn multiple spaces into one space s/ +/ /gio; # add onto the big string $allText .= $_; } # store the length of the string my $textLength = length $allText; # set a counter to 0 (this appears later, trust me) my $textCounter = 0; # close the file close TEXT or die "Error closing file"; # check the file is readable if (!(-r $inputImageName)) { die "Couldn't read $inputImageName"; } # get the optional background colours if ($argc == 4) { ($backRed,$backGreen,$backBlue) = split ',',$backgroundColours; } else { ($backRed,$backGreen,$backBlue) = (0,0,0); } # load the image my $inputImage = newFromPng GD::Image($inputImageName); # Now get the dimensions of the picture my ($xSize,$ySize) = $inputImage->getBounds(); # make an output image # we do this my cloning the output image, it's just a convienant # way of duplicating the palette. my $outputImage = $inputImage->clone(); # get the index of the background colour my $backgroundIndex = $outputImage->colorClosest($backRed,$backGreen,$backBlue); # blank out the background $outputImage->filledRectangle(0,0,$xSize-1,$ySize-1,$backgroundIndex); # the amount we increment is dependant on the font size, so..... ($fontHeight,$fontWidth) = ($font->height,$font->width); # make a buffer image, where we'll be drawing the letters my $bufferImage = new GD::Image($fontWidth,$fontHeight); my $black=$bufferImage->colorAllocate(0,0,0); my $white=$bufferImage->colorAllocate(255,255,255); # start the scan for ($yScan = 0; $yScan < $ySize - 1; $yScan += $fontHeight) { for ($xScan = 0; $xScan < $xSize - 1; $xScan += $fontWidth) { # get the character my $char = substr $allText,$textCounter,1; # increment the counter (reset if necessary) $textCounter++; if ($textCounter == $textLength) { $textCounter = 0; } # write the character in the buffer $bufferImage->filledRectangle(0,0,$fontWidth-1,$fontHeight-1,$black); $bufferImage->string($font,0,0,$char,$white); my ($innerX,$innerY); for ($innerY = 0; $innerY < $fontHeight; $innerY++) { for ($innerX = 0; $innerX < $fontWidth; $innerX++) { my $dotCol = $bufferImage->getPixel($innerX, $innerY); if ($dotCol == $white) { my $originalIndex = $inputImage->getPixel($xScan + $innerX, $yScan + $innerY); my ($or,$og,$ob) = $inputImage->rgb($originalIndex); my $newIndex = $outputImage ->colorExact($or,$og,$ob); $outputImage->setPixel($xScan + $innerX, $yScan + $innerY, $newIndex); } } } } } # output the image open (OUTPUT,"> $outputImageName") or die "couldn't open output file"; binmode OUTPUT; print OUTPUT $outputImage->png; close OUTPUT; # we're done, thank you, it's been a pleasure.