I need to split a large (up to 16384x16384px) image into smaller chunks, usually 512x512. For doing this, I'm using the simple perl script below:
#!/usr/bin/perl
use warnings;
use strict;
my $size = '512x512';
unless ($ARGV[0]) { die "Missing filename as arg" }
unless (-e $ARGV[0]) { die "$ARGV[0] not found.\n" }
my ($newfile, undef) = split(/\./,$ARGV[0]);
system("convert $ARGV[0] -crop $size $newfile" . "_%03d.png");
Now, the thing is, I need to build an index of the smaller pieces which includes the position offset in the original image, for example in the case of a 1024x1024 source image:
image_000.png 0,0
image_001.png 512,0
image_002.png 0,512
image_003.png 512,512
...or something similar. Basically, just to keep track of the position each particular chunk had in the original image.
Since the convert
command passed to system()
I was thinking of just doing a glob of the files and sorting them, as some quick experimentation shows that the smaller chunks are numbered in the order left to right, top to bottom (intuitively) and build the index based on that, but I'm thinking there must be something simpler involving perls own interface to ImageMagick
So my questions then are:
1. What is the Image::Magick
equivalent of convert $ARGV[0] -crop $size $newfile" . "_%03d.png
?
2. Is it possible to build the index based on data from the $image object once I have managed to avoid a system() call?
PS:
- The chunk size doesn't change often. Hardcoding 512 is fine, so there's no need to extract that from
$size
... in fact, I don't know why i chose to have that variable at all. - The Original image size is always divisible by the chunk size, so there's no need to worry about leftovers.
- To make the glob() approach tricky, the images aren't always square. Perhaps using the 3rd column of the
identify
command can be taken into account somehow?
I solved it the only way i know how: Screw perlmagic, and do it via command line instead. The below script works on both rectangular and square images. Index is printed to the screen.