将图像保存在 RAM 上并使用 ImageMagick 对其进行处理
Save image on RAM and work on it using 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但是我不太明白我该如何实现它。
在 php 中使用 ImageMagick 的最简单方法是使用 ImageMagick 扩展 & class。我不建议为此使用 exec 函数。
所以首先,转换图像并将其存储在变量中。
你说你不习惯变量,但从你的代码看来你是,你可能只是不知道。
例如,您的 $output
是一个变量。该变量包含输出完成后的图像(如果成功)。
现在,我不是 100% 确定您的层数组包含什么,如果它的图像或图像的路径,但我希望它的路径,所以我会接受这个假设。
您的第一个 exec
调用进行了转换,我认为这不是必要的,因为您没有输入,您所需要的只是我所看到的 "white image"。
为此,创建一个新的图像对象并创建一个大小和背景颜色正确的新图像:
$image = new Imagick();
$image->newImage(600, 800, "white");
然后你像你一样循环层,但你使用上面创建的 imagemagick 图像而不是 exec:
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
变量将包含合成图像,您可以根据需要return。
$image->setImageFormat('jpg');
return "data:image/jpeg;base64,{base64_encode($image)}";
注:代码未经测试,直接在浏览器中编写。所以它可能需要重写!
我正在做一个项目,客户可以通过将不同的图层(图像)合并为单个图像来创建动态图像,然后将生成的图像显示给客户。目前我的代码是这样的
$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但是我不太明白我该如何实现它。
在 php 中使用 ImageMagick 的最简单方法是使用 ImageMagick 扩展 & class。我不建议为此使用 exec 函数。
所以首先,转换图像并将其存储在变量中。
你说你不习惯变量,但从你的代码看来你是,你可能只是不知道。
例如,您的 $output
是一个变量。该变量包含输出完成后的图像(如果成功)。
现在,我不是 100% 确定您的层数组包含什么,如果它的图像或图像的路径,但我希望它的路径,所以我会接受这个假设。
您的第一个 exec
调用进行了转换,我认为这不是必要的,因为您没有输入,您所需要的只是我所看到的 "white image"。
为此,创建一个新的图像对象并创建一个大小和背景颜色正确的新图像:
$image = new Imagick();
$image->newImage(600, 800, "white");
然后你像你一样循环层,但你使用上面创建的 imagemagick 图像而不是 exec:
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
变量将包含合成图像,您可以根据需要return。
$image->setImageFormat('jpg');
return "data:image/jpeg;base64,{base64_encode($image)}";
注:代码未经测试,直接在浏览器中编写。所以它可能需要重写!