mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-22 16:32:13 -07:00
New mechanism for automatic generation of the puzzle screenshots on
the web, which I hope will also end up being extended to generate both Windows and X icons for each individual puzzle. The mechanism is: for each puzzle there's a save file in the `icons' subdirectory showing a game state which I think is a decent illustration of the puzzle, and then there's a nasty set of scripts which runs each puzzle binary, loads that save file, grabs a screenshot using xwd, and munges it into shape. In order to support this I've added two new options (--redo and --windowid) to all the GTK puzzles, which I don't expect ever to be used outside the icons makefile. I've also added two more options (--load and --id) which force a GTK puzzle to treat its command-line option as a save file or as a game ID respectively (the previous behaviour was always to guess, and sometimes it guessed wrong). [originally from svn r7014]
This commit is contained in:
86
icons/square.pl
Executable file
86
icons/square.pl
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Read an input image, crop its border to a standard width, and
|
||||
# convert it into a square output image. Parameters are:
|
||||
#
|
||||
# - the required total image size
|
||||
# - the output border thickness
|
||||
# - the input image file name
|
||||
# - the output image file name.
|
||||
|
||||
($osize, $oborder, $infile, $outfile) = @ARGV;
|
||||
|
||||
# Determine the input image's size.
|
||||
$ident = `identify -format "%w %h" $infile`;
|
||||
$ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
|
||||
($w, $h) = ($1, $2);
|
||||
|
||||
# Read the input image data.
|
||||
$data = [];
|
||||
open IDATA, "convert $infile rgb:- |";
|
||||
push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
|
||||
close IDATA;
|
||||
# Check we have the right amount of data.
|
||||
$xl = $w * $h;
|
||||
$al = scalar @$data;
|
||||
die "wrong amount of image data ($al, expected $xl) from $img\n"
|
||||
unless $al == $xl;
|
||||
|
||||
# Find the background colour. We assume the image already has a
|
||||
# border, so this is just the pixel colour of the top left corner.
|
||||
$back = $data->[0];
|
||||
|
||||
# Crop rows and columns off the image to find the central rectangle
|
||||
# of non-background stuff.
|
||||
$ystart = 0;
|
||||
$ystart++ while $ystart < $h and scalar(grep { $_ ne $back } map { $data->[$ystart*$w+$_] } 0 .. ($w-1)) == 0;
|
||||
$yend = $h-1;
|
||||
$yend-- while $yend >= $ystart and scalar(grep { $_ ne $back } map { $data->[$yend*$w+$_] } 0 .. ($w-1)) == 0;
|
||||
$xstart = 0;
|
||||
$xstart++ while $xstart < $w and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xstart] } 0 .. ($h-1)) == 0;
|
||||
$xend = $w-1;
|
||||
$xend-- while $xend >= $xstart and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xend] } 0 .. ($h-1)) == 0;
|
||||
|
||||
# Decide how much border we're going to put back on to make the
|
||||
# image perfectly square.
|
||||
$hexpand = ($yend-$ystart) - ($xend-$xstart);
|
||||
if ($hexpand > 0) {
|
||||
$left = int($hexpand / 2);
|
||||
$xstart -= $left;
|
||||
$xend += $hexpand - $left;
|
||||
} elsif ($hexpand < 0) {
|
||||
$vexpand = -$hexpand;
|
||||
$top = int($vexpand / 2);
|
||||
$ystart -= $top;
|
||||
$yend += $vexpand - $top;
|
||||
}
|
||||
$ow = $xend - $xstart + 1;
|
||||
$oh = $yend - $ystart + 1;
|
||||
die "internal computation problem" if $ow != $oh; # should be square
|
||||
|
||||
# And decide how much _more_ border goes on to add the bit around
|
||||
# the edge.
|
||||
$realow = int($ow * ($osize / ($osize - 2*$oborder)));
|
||||
$extra = $realow - $ow;
|
||||
$left = int($extra / 2);
|
||||
$xstart -= $left;
|
||||
$xend += $extra - $left;
|
||||
$top = int($extra / 2);
|
||||
$ystart -= $top;
|
||||
$yend += $extra - $top;
|
||||
$ow = $xend - $xstart + 1;
|
||||
$oh = $yend - $ystart + 1;
|
||||
die "internal computation problem" if $ow != $oh; # should be square
|
||||
|
||||
# Now write out the resulting image, and resize it appropriately.
|
||||
open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
|
||||
for ($y = $ystart; $y <= $yend; $y++) {
|
||||
for ($x = $xstart; $x <= $xend; $x++) {
|
||||
if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
|
||||
print IDATA $data->[$y*$w+$x];
|
||||
} else {
|
||||
print IDATA $back;
|
||||
}
|
||||
}
|
||||
}
|
||||
close IDATA;
|
Reference in New Issue
Block a user