Hello i have big technical problem i need crop image to parts like this:
One parts is 500px x 500px except in the case where there is less space.
Example image size is 1920px x 1080px totaly i have 12 parts of image.
Me problem i have very big image it's 30 000px x 20 000px it's have about 2800parts.
I try to use php imagemagic library
imagemagic command line codes: http://www.ioncannon.net/linux/81/5-imagemagick-command-line-examples-part-1/
with this command i can crop image place: convert flower.jpg -crop 500×500+0+0 flower_crop.jpg
first and seconds arguments width height of part: 500;
the third and fourth arguments it's the from the location started clipping;
I tested crop one part per 20 seconds if i need get 2800 parts i need about: 2800 x 20 / 60 / 60 = 15-16~ hours
I need get fastest result. How i can do it..
full php code:
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/');
At the command line (on a medium spec iMac) I can achieve what you are trying to do in 2 minutes 44 seconds using the following command:
convert -crop 500x500 image.jpg tile%04d.jpg
This way you only read the image once and only execute convert
once, and it works out all the tiles for you, each one 500x500 with names like tile1799.jpg
.
Update
To get it even faster, I did this. First, tile the image into 4 quadrants, called quad00.jpg
, quad01.jpg
, quad02.jpg
and quad03.jpg
like this - notice the @
at the end specifying number of tiles rather than size:
convert -crop 2x2@ image.jpg quad%02d.jpg
Now I can run 4 parallel processes to split the quadrants into 500x500 tiles and keep all my CPU cores busy:
#!/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
The splitting the original image into 4 quadrants took 52 seconds, and then splitting all four quadrants into 500x500 tiles in parallel took a further 7 seconds, for a total time of 59 seconds.
In answer to your further question about sizing the inityial 4 quadrants unequally, you are at liberty to do the initial four quadrants however you like - you know your images better than me! In fact, depending on your CPU, you may be better off with 8 initial tiles, or maybe 2. Anyway, you will need to experiment. In order to do that, you can calculate the size (width and height) of your image like this and then do some maths to decide how you want to do the initial quadrants, or halves or whatever:
# Get width
w=$(identify -format %w image.jpg)
echo $w
30000
# Get height
h=$(identify -format %h image.jpg)
echo $h
20000