I'm trying to use ImagickDraw on PHP to draw an image using a very large number (~100,000) of circle() rectangle() etc calls. These are split between the 4 cmyk channels so each channel gets around ~30k calls.
The actual circle() and rectangle() calls themselves are really fast and that entire part of the program runs in less than a second; then I hit the part where I use drawImage on each of the 4 separate ImagickDraw objects and this takes >15 seconds for each layer to run... understood it's a very complicated image, but is there any way to speed this up?
I've considered using pthreads, having a separate pthread for each of the 4 ImagickDraw objects, and this just caused the program to hang:
class Render extends Thread
{
public $im;
private $svg;
public function __construct($width, $height, $bg, $svg)
{
$this->im = new Imagick();
$this->svg = $svg;
$this->im->newImage($width, $height, $bg);
}
public function run()
{
$id = new ImagickDraw();
$id->setVectorGraphics($this->svg);
$this->im->drawImage($id);
}
}
$threads = [];
$imarray = [];
foreach($drawar as $c=>$s){
$threads[$c] = new Render($finalsize['width'], $finalsize['height'], 'white', $s);
$threads[$c]->start();
}
foreach($threads as $c=>$p){
$p->join();
$imarray[$c] = $p->im;
echo "Got {$c} data\n";
}
Thank you!
I'm surprised that i) works ii) is that fast.
What I'd suggest trying is forget making this many individual calls to Imagick.
Instead generate an SVG XML document by hand, using the appropriate svg circle and rectangle tags. Then either use Imagick to composite/convert that image into the output image format you want.
Yeah, that's not going to work. The underlying C library isn't compatible with pthreads.