~ubuntu-branches/ubuntu/saucy/sgt-puzzles/saucy

« back to all changes in this revision

Viewing changes to icons/square.pl

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings
  • Date: 2008-04-13 17:39:38 UTC
  • mto: (1.1.6 upstream) (3.1.2 lenny)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20080413173938-nnrvlls98m6ky6eq
ImportĀ upstreamĀ versionĀ 7983

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl 
 
2
 
 
3
# Read an input image, crop its border to a standard width, and
 
4
# convert it into a square output image. Parameters are:
 
5
#
 
6
#  - the required total image size
 
7
#  - the output border thickness
 
8
#  - the input image file name
 
9
#  - the output image file name.
 
10
 
 
11
($osize, $oborder, $infile, $outfile) = @ARGV;
 
12
 
 
13
# Determine the input image's size.
 
14
$ident = `identify -format "%w %h" $infile`;
 
15
$ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
 
16
($w, $h) = ($1, $2);
 
17
 
 
18
# Read the input image data.
 
19
$data = [];
 
20
open IDATA, "convert -depth 8 $infile rgb:- |";
 
21
push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
 
22
close IDATA;
 
23
# Check we have the right amount of data.
 
24
$xl = $w * $h;
 
25
$al = scalar @$data;
 
26
die "wrong amount of image data ($al, expected $xl) from $infile\n"
 
27
  unless $al == $xl;
 
28
 
 
29
# Find the background colour, by looking around the entire border
 
30
# and finding the most popular pixel colour.
 
31
for ($i = 0; $i < $w; $i++) {
 
32
    $pcount{$data->[$i]}++; # top row
 
33
    $pcount{$data->[($h-1)*$w+$i]}++; # bottom row
 
34
}
 
35
for ($i = 1; $i < $h-1; $i++) {
 
36
    $pcount{$data->[$i*$w]}++; # left column
 
37
    $pcount{$data->[$i*$w+$w-1]}++; # right column
 
38
}
 
39
@plist = sort { $pcount{$b} <=> $pcount{$a} } keys %pcount;
 
40
$back = $plist[0];
 
41
 
 
42
# Crop rows and columns off the image to find the central rectangle
 
43
# of non-background stuff.
 
44
$ystart = 0;
 
45
$ystart++ while $ystart < $h and scalar(grep { $_ ne $back } map { $data->[$ystart*$w+$_] } 0 .. ($w-1)) == 0;
 
46
$yend = $h-1;
 
47
$yend-- while $yend >= $ystart and scalar(grep { $_ ne $back } map { $data->[$yend*$w+$_] } 0 .. ($w-1)) == 0;
 
48
$xstart = 0;
 
49
$xstart++ while $xstart < $w and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xstart] } 0 .. ($h-1)) == 0;
 
50
$xend = $w-1;
 
51
$xend-- while $xend >= $xstart and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xend] } 0 .. ($h-1)) == 0;
 
52
 
 
53
# Decide how much border we're going to put back on to make the
 
54
# image perfectly square.
 
55
$hexpand = ($yend-$ystart) - ($xend-$xstart);
 
56
if ($hexpand > 0) {
 
57
    $left = int($hexpand / 2);
 
58
    $xstart -= $left;
 
59
    $xend += $hexpand - $left;
 
60
} elsif ($hexpand < 0) {
 
61
    $vexpand = -$hexpand;
 
62
    $top = int($vexpand / 2);
 
63
    $ystart -= $top;
 
64
    $yend += $vexpand - $top;
 
65
}
 
66
$ow = $xend - $xstart + 1;
 
67
$oh = $yend - $ystart + 1;
 
68
die "internal computation problem" if $ow != $oh; # should be square
 
69
 
 
70
# And decide how much _more_ border goes on to add the bit around
 
71
# the edge.
 
72
$realow = int($ow * ($osize / ($osize - 2*$oborder)));
 
73
$extra = $realow - $ow;
 
74
$left = int($extra / 2);
 
75
$xstart -= $left;
 
76
$xend += $extra - $left;
 
77
$top = int($extra / 2);
 
78
$ystart -= $top;
 
79
$yend += $extra - $top;
 
80
$ow = $xend - $xstart + 1;
 
81
$oh = $yend - $ystart + 1;
 
82
die "internal computation problem" if $ow != $oh; # should be square
 
83
 
 
84
# Now write out the resulting image, and resize it appropriately.
 
85
open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
 
86
for ($y = $ystart; $y <= $yend; $y++) {
 
87
    for ($x = $xstart; $x <= $xend; $x++) {
 
88
        if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
 
89
            print IDATA $data->[$y*$w+$x];
 
90
        } else {
 
91
            print IDATA $back;
 
92
        }
 
93
    }
 
94
}
 
95
close IDATA;