I'm told that JPEG is at its most efficient if the image dimensions are exact multiple of 8 pixels. This program crops a PBM/PGM/PPM image to the nearest 8x8 tile multiple, or to any tile size you specify on the command line.

Includes a small hack to identify a PNM file without using pnmfile(1). Needs the pnmcut(1) tool.

Update 27/12/02: Removed use diagnostics; on the advice of tachyon.

#!/usr/bin/env perl # pnmjpegcrop - trim a pnm to 8 by 8, or whatever specified on cmd lin +e # created by stewart on 02002/10/25 # reads a whole PNM file from stdin into core, so a bit more of a # hog than it should be. Writes suitably trimmed PNM stream to stdout. use strict; use warnings; use integer; # hey, I actually use this here! my $modulo=8; # real default # scan arguments for something like -NN for default trim tile size if ($#ARGV > -1) { if ($ARGV[0] =~ /^\-+[0-9]+/) { $modulo=shift(@ARGV); $modulo =~ s/\D+//g; } } $modulo=8 unless (defined($modulo)); # sanity checks $modulo=1 if ($modulo < 1); my @file=<>; # slurp all input my @pnminfo=(); # read pnm header; could use pnmfile(1) or identify(1) for this # but since pnm is such a simple format ... for (my $i=0; $i <=$#file; $i++) { $_=$file[$i]; # don't use foreach() as it modifies @ +file s/^\s+//; # clean leading w/s next if (m/^\#/); # skip comments last if ($#pnminfo == 2); # exit if we've read three things s/\s+$//; # normalize rest of w/s s/\s+/ /g; my @a=split(' ', $_); push @pnminfo, @a; } my ($type, $width, $height) = @pnminfo; die "Input is not PNM\n" unless ($type =~ m/^P\d$/); # die on wrong in +put # tile mustn't be > width or height ($modulo)=sort {$a <=> $b} ($modulo, $width, $height); my $iwidth=($width/$modulo)*$modulo; # these are integer divides, reme +mber my $iheight=($height/$modulo)*$modulo; my $xoff=($width-$iwidth)/2; # choose offset for as near centred as + we can my $yoff=($height-$iheight)/2; if (($width == $iwidth) and ($height == $iheight)) { # file already a multiple of $modulo x $modulo pixels, so leave it + alone print @file; # splat whole file out to stdout } else { # use old-style pnmcut arguments so we're compatible # should probably be more careful with pnmcut path for non-trusted + use. open(PNMCUT, "| pnmcut $xoff $yoff $iwidth $iheight") or die "pnmcut failed: $!\n"; print PNMCUT @file; # splat whole file out through pnmcut close(PNMCUT); } exit;

Replies are listed 'Best First'.
Re: Crop PNM files for JPEG conversion
by tachyon (Chancellor) on Dec 27, 2002 at 08:56 UTC

    Hi, I would drop the use diagnostics from any code you see as worth posting. While it may be useful in development if you are new to Perl it is not needed in production code as slows loading and uses a chunk of memory for no good reason.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print