Использование Image::Magick, чтобы разделить изображение на более мелкие порции и получить относительную позицию каждого порции.

Мне нужно разделить большое (до 16384x16384px) изображение на более мелкие куски, обычно 512x512. Для этого я использую простой скрипт на 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");

Теперь дело в том, что мне нужно построить индекс меньших частей, который включает смещение позиции в исходном изображении, например, в случае исходного изображения 1024x1024:

image_000.png    0,0
image_001.png    512,0
image_002.png    0,512 
image_003.png    512,512

... или что-то подобное. В основном, просто чтобы отслеживать положение каждого конкретного куска в исходном изображении.

Так как convert команда передана system() Я думал о том, чтобы просто сделать глобус файлов и отсортировать их, так как некоторые быстрые эксперименты показывают, что меньшие порции нумеруются в порядке слева направо, сверху вниз (интуитивно) и строят индекс на основе этого, но я ' я думаю, что должно быть что-то более простое, включая собственный интерфейс Perls для ImageMagick


Итак, мои вопросы:

1. Что такое Image::Magick эквивалент convert $ARGV[0] -crop $size $newfile" . "_%03d.png?

2. Можно ли построить индекс на основе данных из объекта $image, если мне удалось избежать вызова system()?

PS:

  • Размер чанка не часто меняется. Жесткое кодирование 512 хорошо, поэтому нет необходимости извлекать это из $size... на самом деле, я не знаю, почему я выбрал эту переменную вообще.
  • Исходный размер изображения всегда делится на размер фрагмента, поэтому не нужно беспокоиться об остатках.
  • Чтобы сделать glob() сложным, изображения не всегда квадратные. Возможно, используя 3-й столбец identify Команду можно как-то учесть?

1 ответ

Решение

Я решил это только так, как я знаю: винт perlmagic, и вместо этого сделать это через командную строку. Приведенный ниже скрипт работает как с прямоугольными, так и с квадратными изображениями. Указатель выводится на экран.

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__
Другие вопросы по тегам