简体   繁体   English

使用Image :: Magick将图像分割成较小的块并获取每个块的相对位置

[英]Using Image::Magick to split an image into smaller chunks and get relative position of each chunk

I need to split a large (up to 16384x16384px) image into smaller chunks, usually 512x512. 我需要将大图片(最大16384x16384px)拆分为较小的块,通常为512x512。 For doing this, I'm using the simple perl script below: 为此,我使用以下简单的perl脚本:

#!/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: 现在,我需要构建一个较小的索引,其中包括原始图像中的位置偏移,例如在1024x1024源图像的情况下:

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 自从将convert命令传递给system()以来,我一直在考虑对文件进行全局处理并对其进行排序,因为一些快速实验表明,较小的块按从左到右,从上到下(直观)的顺序编号并进行构建基于此的索引,但是我认为必须有一些更简单的方法,包括Perls自己的ImageMagick接口


So my questions then are: 所以我的问题是:

1. What is the Image::Magick equivalent of convert $ARGV[0] -crop $size $newfile" . "_%03d.png ? 1.什么是Image::Magick等效于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? 2.一旦设法避免了system()调用,是否可以基于$ image对象中的数据构建索引?

PS: 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. 硬编码512很好,因此不需要从$size提取出来……实际上,我根本不知道为什么我选择使用该变量。
  • 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. 为了使glob()方法更加棘手,图像并不总是方形的。 Perhaps using the 3rd column of the identify command can be taken into account somehow? 也许可以通过某种方式考虑使用identify命令的第三列?

I solved it the only way i know how: Screw perlmagic, and do it via command line instead. 我用我知道的唯一方法解决了它:拧上perlmagic,然后通过命令行代替。 The below script works on both rectangular and square images. 以下脚本适用于矩形和正方形图像。 Index is printed to the screen. 索引打印到屏幕上。

use warnings;
use strict;

my $size = '512x512';
my $offset = 512;

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");

my @files = glob($newfile . "_*");
@files = sort(@files);

my (undef, undef, $origsize) = split(/\s+/,`identify $ARGV[0]`);
my ($maxX, $maxY) = split(/x/,$origsize);

$maxX /= $offset;
$maxY /= $offset;

my $x = 0;
my $y = 0;
foreach my $file (@files)
{
        print "$file\t" . $x * $offset . "\t" . $y * $offset . "\n";
        $x++;

        if ($x >= $maxX)
        {
                $x = 0;
                $y++;
        }
}


__END__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM