PHP ImageMagick разбивает большое изображение на плитки

Я пытаюсь разбить большое изображение на более мелкие плитки. Я попробовал это с помощью PHP ImageMagick cropImage() и смог успешно сделать это со следующим кодом.

for($w = 0; $w < ($large_image_width/$tile_width); $w++){
    for($h = 0; $h < ($large_image_height/$tile_height); $h++){
        $X = $w*$tile_width;
        $Y = $h*$tile_height;

        $image = new Imagick($input_file);
        $image->cropImage($tile_width,$tile_height, $X,$Y);
        $image->writeImage("X" . ($w+1) . "Y" . ($h+1) . ".jpg");
    }
}

Но он перебирает каждый размер плитки и загружает изображение снова и снова.

Проведя дополнительные исследования, я нашел эту ссылку, который представляет собой одну строку с использованием командной строки.

convert -crop $WIDTHx$HEIGHT@ huge_file.png  tile_%d.png

Мне интересно, есть ли у расширения PHP ImageMagick какая-либо функция, позволяющая делать то же самое. Также мне удобно переключаться на Perl или другую библиотеку, например GD.


person Jithin    schedule 11.08.2014    source источник


Ответы (2)


Вы можете уменьшить $input_file ввод-вывод, загрузив изображение один раз, а затем клонировав объект.

$source_image = new Imagick($input_file);
for($w = 0; $w < ($large_image_width/$tile_width); $w++){
    for($h = 0; $h < ($large_image_height/$tile_height); $h++){
        $X = $w*$tile_width;
        $Y = $h*$tile_height;

        $image = clone $source_image;
        $image->cropImage($tile_width,$tile_height, $X,$Y);
        $image->writeImage("X" . ($w+1) . "Y" . ($h+1) . ".jpg");
    }
}

Вы также можете оптимизировать и уменьшить цикл for или просто вызвать один лайнер напрямую.

system("convert -crop $WIDTHx$HEIGHT@ $input_file  tile_%d.png");
person emcconville    schedule 11.08.2014
comment
Большое спасибо за способ клонирования. И да, я знаю о системной команде. Я имел в виду, есть ли какой-либо метод в самом расширении PHP ImageMagick? - person Jithin; 12.08.2014
comment
В самом расширении PECL его нет. Вы можете имитировать поведение, комбинируя Imagick::cropImage и Imagick::setImagePage, но проще всего то, что вы уже делаете. - person emcconville; 12.08.2014

libvips имеет связывание php сейчас, и он может выполнить эту задачу очень быстро, используя лишь немного памяти.

Например:

#!/usr/bin/env php
<?php

require __DIR__ . '/vendor/autoload.php';

use Jcupitt\Vips;

$im = Vips\Image::newFromFile($argv[1]);
$im->dzsave($argv[2], ["overlap" => 0, "tile-size" => 256, "depth" => "one"]);

На этом ноутбуке с изображением jpeg 10k x 10k я вижу:

$ time ./try260.php ~/pics/wtc.jpg x
real    0m2.262s
user    0m3.596s
sys 0m1.256s

И он создал 1369 файлов jpeg в x_files:

$ ls x_files/0/ | wc
   1369    1369   14319

Здесь есть запись в блоге об операторе dzsave (здесь используется libvips):

http://libvips.blogspot.co.uk/2013/03/making-deepzoom-zoomify-and-google-maps.html

person jcupitt    schedule 05.06.2017