2017-05-31 34 views
0

我正在处理客户机可以通过将不同图层(图像)合并到单个图像中然后将生成的图像显示给客户机来创建动态图像的项目。目前,我的代码是这样的将图像保存到RAM上并使用ImageMagick对其进行处理

$output = uniqid().'.jpg'; 
exec('convert -size 600x800 xc:white '.$output); 
$layers = array(//array of about hundreds of PNG images); 
foreach($layers as $key => $singleLayer) 
{ 
    $layerIs = $singleLayer['image']; 
    $positionsXY = explode(',', $singleLayer['xy']); 
    exec('composite -geometry +'.$positionsXY[0].'+'.$positionsXY[1].' '.$layerIs.' '.$output.' '.$output); 
} 
$base64 = base64_encode(file_get_contents($output)); 
unlink($output); 
return 'data:image/jpeg;base64,'.$base64; 

在我上面的代码中,我生成一个白色的背景图像,然后就可以合并多个PNG图像,这些图像是100多。虽然每次还保存此图像中的一个图层合并,然后在删除生成的图像后将最终图像输出到客户端。这一切都需要大约15秒钟的时间。

所以,我的问题是如果ImageMagick有一个选项,可以让我在RAM上保存图像,而不是将图像保存在硬盘上,这反过来可以加快我的处理速度?

虽然我发现这个http://www.imagemagick.org/discourse-server/viewtopic.php?t=20295,但是我不明白怎么实现它。

+0

您可以尝试使用image magick的readImageBlob函数:http://php.net/manual/en/imagick.readimageblob.php并使用图像magick对象的__toString方法将图像输出为变量。 – Jite

+0

@Jite我在ImageMagick中并不聪明。如果你不介意可以用很少的代码来详细说明,那么我可以更好地理解它。请注意,我使用exec()命令来处理ImageMagick而不是PHP程序语言。因此,使用变量会造成一些混淆: –

+0

我会先推荐使用imagemagick的php扩展名,这是可能的吗?检查你的'phpinfo()'并查看它是否安装。根据答案,我会尝试给你一些进一步的解释。 – Jite

回答

1

在php中使用ImageMagick的最简单方法是使用ImageMagick扩展&类。我不会推荐使用它的exec函数。

首先,转换图像并将其存储在一个变量中。
你说你不习惯变量,但通过你的代码看起来像你,你可能只是不知道它。
例如,您的$output是一个变种。变量包含输出后的图像(如果成功)。

现在,我不是100%确定你的图层数组包含什么,如果它的图像或图像路径,但我期望它的路径,所以我会去那个假设。

你的第一个exec呼叫做转换,我不认为这是nessesery,因为你没有输入,你所需要的只是一个我能看到的“白色图像”。
要做到这一点,创建一个新的图像对象,并创建一个新的形象是正确的大小和背景色:

$image = new Imagick(); 
$image->newImage(600, 800, "white"); 

然后,您可以通过层层循环,你这样做,但不是EXEC使用ImageMagick的图像上面创建:

foreach($layers as $key => $singleLayer) { 
    $layerIs = $singleLayer['image']; 
    $positionsXY = explode(',', $singleLayer['xy']); 
    // Each loop should load the image into a new imagemagick object, but we release it when the scope is exited. 
    $layer = new IMagick($layerIs); 
    $image->compositeImage($layer, Imagick::COMPOSITE_DEFAULT, $positionsXY[0], $positionsXY[1]); 
} 

当循环完成后,$image变量将包含合成图像,正如你愿意,你可以返回。

$image->setImageFormat('jpg'); 
return "data:image/jpeg;base64,{base64_encode($image)}"; 

注:代码没有进行测试,并直接在浏览器中编写的。所以它可能需要重写!

+0

太棒了! Jite你的代码工作得很好。但是为什么它在性能方面没有任何区别。它将花费相同的15秒来完成处理。 –

+0

我会认为真正的瓶颈是加载图层组合中使用的100层图层。我不确定可以通过使用更小的图像或更少的图像进行优化,但这取决于它们的使用方式。图像处理通常是相当繁重的工作,所以可能需要一些时间,但是你需要花时间去处理它。 – Jite

+0

如果您觉得答案回答了问题,请随时将其标记为正确和/或最多投票! – Jite

相关问题