#!/usr/bin/perl -w
# Expand pixels in a PPM to make mosaic like images.
#
# To do: separate color choices for each border.
# user-defined pixel manipulation function.
#
# Benjamin Elijah Griffin 28 Feb 2003
use strict;
use integer;
use Image::PPMlib;
use vars qw( $id $arg $err $i $j $k $r $g $b $br $bg $bb $tri
$inforef @line @out $pc $pix $mpix
$file $bmode $bpixels $bpT $bpB $bpL $bpR $pixels
$VERSION
);
while (defined($ARGV[0]) and $ARGV[0] =~ /^-(.*)/) {
$arg = $1; # stripped of first hyphen
shift;
if ($arg eq '-help' or $arg eq '-version' or $arg eq 'v') {
&usage(0);
} elsif ($arg eq 'b' or $arg eq '-border') {
$bmode = shift;
if ($bmode eq 'none' or $bmode eq 'dark' or $bmode eq 'light') {
1; # valid mode that requires no processing now
} elsif ($bmode eq 'darker' or $bmode eq 'lighter') {
$bmode =~ s/er$//;
# if any border, apply top and left now
if($bmode ne 'none' and ($bpT or $bpL)) {
for ($k = 0; $k < $bpT; $k ++) { # top border, top $bpT rows
$out[$k] .= $pix x $pc;
}
for ($k = 0; $k < $pixels; $k ++) { # left border, after $bpT rpws
$out[$k + $bpT] .= $pix x $bpL;
}
}
# main pixel body
$mpix = $Image::PPMlib::decraw{$line[$j][0]} .
$Image::PPMlib::decraw{$line[$j][1]} .
$Image::PPMlib::decraw{$line[$j][2]};
for ($k = 0; $k < $pixels; $k ++) { # inside main pixel, after $bpT rows
$out[$k + $bpT] .= $mpix x $pixels;
}
# if any border, apply bottom and right now
if($bmode ne 'none' and ($bpB or $bpR)) {
for ($k = 0; $k < $bpB; $k ++) { # bottom border, after $bpT + $pixels
$out[$k + $pixels + $bpT] .= $pix x $pc;
}
for ($k = 0; $k < $pixels; $k ++) { # right border, after $bpT rows
$out[$k + $bpT] .= $pix x $bpR;
}
}
} # end j: per pixel loop
for($k = 0; $k < $bpT + $bpB + $pixels; $k ++) {
# if no border, those strings will still be '' and are safe to print
print $out[$k];
}
if(@line != $$inforef{width}) {
warn "$id: ran out of pixels prematurely\n";
last;
}
} # for line of height
sub usage($) {
my $rc = shift;
print STDERR <<"ProgramUsage";
$id version $VERSION usage:
ppmmosaic reads PPM(5) files and makes larger pixelated versions of them,
with several border options.
Arguments:
-b MODE --border MODE MODE can be black, white, red, green,
blue, fixed:RGB, lighter, darker, or
none. RGB can 6 hex digits or a colon-
seperated decimal triple. 'lighter' and
'darker' are 10% changed from inner pixel
-e SIZE --borderpixels SIZE make the border be SIZE pixels (total, if
odd top and left borders will be larger)
-e T,B,L,R --borderpixels T,B,L,R set sizes for Top, Bottom, Left, and
Right borders
-p SIZE --pixels SIZE make the tile be SIZE pixels (plus border)
-- end arguments
bordermode defaults to none, borderpixels defaults to 1, pixels defaults to 10
Examples:
ppmmosaic -e 5 -p 20 -b fixed:255:150:200 foo.ppm > new-foo.ppm
If foo.ppm was 10x10, the new image will be 250x250, with pink
borders 3 pixels on top and left, 2 pixels on bottom and right
around each of the original pixels, which will now be 20x20 in
size.
ppmmosaic --borderpixels 2 --border fixed:808080 --pixels 6 bar.ppm \
> new-bar.ppm
Image new-bar.ppm will be 8 times larger than bar.ppm with 1 pixel
all around gray borders on the 6x6 tiles from bar.ppm, looking
something like a mosaic complete with grout.
ppmmosaic -e 1,0,0,0 --border black --pixels 1 bar.ppm > new-bar.ppm
Image new-bar.ppm will be twice as tall with a black line between
each row. If bar.ppm had previously been compressed 50% vertically,
it now has an early CRT scan-line look to it.
ProgramUsage
exit $rc;
}
__END__
=pod
=head1 NAME
ppmmosaic - make mosaic images by expanding pixels into bordered tiles
=head1 DESCRIPTION
ppmmosaic reads PPM(5) files and makes larger pixelated versions of them,
with several border options. Such images can look like simple block mosaics,
eg pick a big value for inner pixel size, and small border evenly sized on
all edges. Or venetian blind effects can be created by having borders in
one dimension only.
Options:
=over 4
=item *
-b MODE --border MODE
MODE can be C<black>, C<white>, C<red>, C<green>,
C<blue>, C<fixed:>I<RGB>, C<lighter>, C<darker>, or
C<none>.
For fixed color borders, the RGB value can 6 hex digits (eg "99CC33")
or a colon-seperated decimal triple (eg "153:204:51"). The C<black>,
C<white>, etc, border options are short hand for C<fixed:000000>,
C<fixed:FFFFFF>, etc.
The 'lighter' and 'darker' options are 10% changed from inner pixel.
Default is C<none>.
=item *
-e SIZE --borderpixels SIZE
Makes the border be SIZE pixels total. If SIZE is
odd, the top and left borders will be larger.
So C<-e 5> is equivilent to C<-e 3,2,3,2>
making the top and left borders three pixels,
and the bottom and right borders two pixels.
Default is equivilent to C<-e 2>.
=item *
-e T,B,L,R --borderpixels T,B,L,R
Sets the sizes for Top, Bottom, Left, and Right borders
individually.
Default is equivilent to C<-e 1,1,1,1>
=item *
-p SIZE --pixels SIZE
Makes the inner pixel tile be SIZE pixels. The border goes around
this inner pixel.
Default is C<10>.
=item *
--
Marks the end of the arguments
=item *
--help
Show a help message and exit.
=item *
--version
Same as C<--help>.
=back
=head1 COPYRIGHT
Copyright 2003 by Eli the Bearded / Benjamin Elijah Griffin.
Released under the same license(s) as Perl.
=head1 AUTHOR
Eli the Bearded originally the Image::PPMlib to make a script
very much like this one easier to code.
=head1 CPAN INFO
=head1 SCRIPT CATEGORIES
Image
=head1 README
ppmmosaic - make mosaic images by expanding pixels into bordered tiles
=head1 PREREQUISITES
This uses the C<strict>, C<vars>, C<integer>, and C<Image::PPMlib> modules.