PHP части изображения из изображения (CROP)

Здравствуйте, у меня большая техническая проблема, мне нужно обрезать изображение на такие части:

введите описание изображения здесь
Одна часть составляет 500 х 500 пикселей, за исключением случаев, когда места меньше.

Примерный размер изображения составляет 1920 x 1080 пикселей. У меня 12 частей изображения.

У меня проблема у меня очень большое изображение его 30 000 пикселей x 20 000 пикселей это о 2800parts.

Я пытаюсь использовать php imagemagic library

Коды командной строки imagemagic: http://www.ioncannon.net/linux/81/5-imagemagick-command-line-examples-part-1/

с помощью этой команды я могу обрезать место изображения: convert flower.jpg -crop 500×500+0+0 flower_crop.jpg

первый и второй аргументы ширина высота части: 500;

третий и четвертый аргументы — это то, с какого места началось отсечение;

Я протестировал обрезку по одной части за 20 секунд, если мне нужно получить 2800 частей, которые мне нужны: 2800 x 20 / 60 / 60 = 15-16~ hours Мне нужно получить быстрый результат. Как я могу это сделать ..

полный код php:

public function cutImgIntoPieces($imgPieceSizeWidth, $imgPieceSizeHeight, $outputDir) {
$pieceWidth = $imgPieceSizeWidth;
$pieceHeight = $imgPieceSizeHeight;

$divWidth = floor($this->getImgWidth() / $pieceWidth);
$modWidth = $this->getImgWidth() % $pieceWidth;
$divHeight = floor($this->getImgHeight() / $pieceHeight);
$modHeight = $this->getImgHeight() % $pieceHeight;

for ($i = 0; $i <= $divWidth; $i++) {
for ($j = 0; $j <= $divHeight; $j++) {

$pieceWidth = ($i == $divWidth ? $modWidth : $imgPieceSizeWidth);
$pieceHeight = ($j == $divHeight ? $modHeight : $imgPieceSizeHeight);

exec("cd ". $this->getDirName() . " & convert " . $this->getFullFileName() . " -crop " . $pieceWidth . "x" . $pieceHeight . "+" . $imgPieceSizeWidth * $i . "+" . $imgPieceSizeHeight * $j . " " . $i . "_" . $j . ".jpg");

}
}
}$img->cutImgIntoPieces(500, 500, 'C:/xampp/htdocs/');

0

Решение

В командной строке (на iMac средней спецификации) я могу добиться того, что вы пытаетесь сделать, за 2 минуты 44 секунды, используя следующую команду:

convert -crop 500x500 image.jpg tile%04d.jpg

Таким образом, вы читаете изображение только один раз и выполняете только convert один раз, и он обрабатывает все плитки для вас, каждый 500×500 с именами, такими как tile1799.jpg,

Обновить

Чтобы сделать это еще быстрее, я сделал это. Сначала разбейте изображение на 4 сектора, называемые quad00.jpg, quad01.jpg, quad02.jpg а также quad03.jpg вот так — заметьте @ в конце укажите количество плиток, а не размер:

convert -crop 2x2@ image.jpg quad%02d.jpg

Теперь я могу запустить 4 параллельных процесса, чтобы разделить квадранты на плитки размером 500×500 и сохранить занятость всех процессорных ядер:

#!/bin/bash
convert -crop 500x500 quad00.jpg tile0-%04d.jpg &
convert -crop 500x500 quad01.jpg tile1-%04d.jpg &
convert -crop 500x500 quad02.jpg tile2-%04d.jpg &
convert -crop 500x500 quad03.jpg tile3-%04d.jpg &
wait

Разделение исходного изображения на 4 квадранта заняло 52 секунды, а затем параллельное разделение всех четырех квадрантов на плитки размером 500×500 заняло еще 7 секунд, в общей сложности 59 секунд.

Отвечая на ваш дальнейший вопрос о неравном размере четырех начальных квадрантов, вы можете делать первые четыре квадранта так, как вам нравится — вы знаете свои изображения лучше меня! На самом деле, в зависимости от вашего процессора, вам может быть лучше с 8 начальными тайлами или, может быть, 2. В любом случае, вам придется экспериментировать. Чтобы сделать это, вы можете рассчитать размер (ширину и высоту) вашего изображения следующим образом, а затем сделать некоторые математические расчеты, чтобы решить, как вы хотите сделать начальные квадранты, или половинки или что-то еще:

# Get width
w=$(identify -format %w image.jpg)

echo $w
30000

# Get height
h=$(identify -format %h image.jpg)

echo $h
20000
1

Другие решения

Других решений пока нет …