1 | #!/usr/bin/perl -w |
---|
2 | |
---|
3 | # split.pl |
---|
4 | # Split all of the images within a file into segments. |
---|
5 | # The command line parameters are the filename, number of rows, |
---|
6 | # and number of columns. |
---|
7 | # |
---|
8 | use Image::Magick; |
---|
9 | |
---|
10 | my ($filename, $hgrid, $vgrid, $status) ; |
---|
11 | |
---|
12 | # Check to see if the three required parameters are provided... |
---|
13 | # $vgrid is the number of rows, $hgrid is the number of columns |
---|
14 | # |
---|
15 | if (($filename = $ARGV[0]) && |
---|
16 | ($vgrid = $ARGV[1]) && |
---|
17 | ($hgrid = $ARGV[2])) { |
---|
18 | |
---|
19 | my $images = new Image::Magick; # source file |
---|
20 | my $images2 = new Image::Magick; # used later as a temp image |
---|
21 | $status = $images->Read("$filename"); # file may be multi-image |
---|
22 | die "Couldn't open file $filename!" if "$status"; |
---|
23 | |
---|
24 | my $imagecount = @$images; # number of scenes |
---|
25 | $images->Set(adjoin=>0); # split into separate images |
---|
26 | |
---|
27 | print STDERR "Writing scene files...\n"; |
---|
28 | # If it is a multi-image file, write each of the |
---|
29 | # individual scenes for reference purposes... |
---|
30 | # |
---|
31 | $images->Write() if ($imagecount>1); |
---|
32 | |
---|
33 | my ($width, $height) = $images->Get('width', 'height'); |
---|
34 | my @x = (0); # This list contains the x values of the crop grid |
---|
35 | my @y = (0); # This contains the y values |
---|
36 | |
---|
37 | # Set up the horizontal crop grid. |
---|
38 | # Because of rounding errors, not all tiles will be the same |
---|
39 | # dimensions unless $width is a multiple of $hgrid. To make sure |
---|
40 | # we don't lose any pixels, the last tile in the grid should |
---|
41 | # always crop to the width of the image... |
---|
42 | # |
---|
43 | foreach my $count (1..$hgrid) { |
---|
44 | if ($count == $hgrid) { |
---|
45 | push @x, $width; # crop to the edge |
---|
46 | } else { |
---|
47 | # otherwise the width of the tile should be int($width/$hgrid) |
---|
48 | # |
---|
49 | push @x, $count * int($width/$hgrid); |
---|
50 | } |
---|
51 | } |
---|
52 | |
---|
53 | # Now set up the vertical crop grid... |
---|
54 | # |
---|
55 | foreach my $count (1..$vgrid) { |
---|
56 | if ($count == $vgrid) { |
---|
57 | push @y, $height; |
---|
58 | } else { |
---|
59 | push @y, $count * int($height/$vgrid); |
---|
60 | } |
---|
61 | } |
---|
62 | |
---|
63 | my $geometry; # This will be the string passed to Crop() |
---|
64 | foreach my $xcount (0..$hgrid-1) { |
---|
65 | foreach my $ycount (0..$vgrid-1) { |
---|
66 | # The Clone() method copies the content of $images |
---|
67 | # |
---|
68 | $images2 = $images->Clone(); |
---|
69 | |
---|
70 | # Set up the geometry string |
---|
71 | # |
---|
72 | $geometry = ($x[$xcount+1] - $x[$xcount])."x". |
---|
73 | ($y[$ycount+1] - $y[$ycount]). |
---|
74 | "+$x[$xcount]+$y[$ycount]"; |
---|
75 | print STDERR "Crop $geometry\n"; |
---|
76 | $images2->Crop("$geometry"); |
---|
77 | |
---|
78 | # Write a file consisting of the cropped tile for |
---|
79 | # each scene. The filename will be in the form |
---|
80 | # filename.x.y.scene where x and y is the coordinate of |
---|
81 | # the upper left coordinate of the tile. |
---|
82 | # |
---|
83 | $images2->Write("jpg:tile-$xcount-$ycount.jpg"); |
---|
84 | undef $images2; # Clean up |
---|
85 | } |
---|
86 | } |
---|
87 | undef $images; # Clean up |
---|
88 | print STDERR "Done!...\n"; |
---|
89 | } else { |
---|
90 | print "Usage: perl split.pl filename rows columns\n"; |
---|
91 | } |
---|