我有一个允许用户上传图片的应用程序。我使用的测试用例是一个1.6MB的jpeg,尺寸为3872 x 2592px。后端的上传脚本会将上传的图像调整为另外6种格式:
我知道这很多但是相信我,我需要这个。我使用Code Igniter的Image Manipulation类进行调整大小,该类使用GD,GD2或ImageMagick进行调整大小。我首先将它配置为使用GD2,并注意到总调整大小过程需要11秒。
由于用户必须等待此过程,因此不可接受。经过大量阅读后,我了解到ImageMagick是一个更加快速有效的操作库,所以我切换到了:
$sourceimage = $data['filedata']['file_path'] . $data['imagedata']['user_id'] . "/" . $imageid . $data['filedata']['file_ext'];
$resize_settings['image_library'] = 'imagemagick';
$resize_settings['library_path'] = '/usr/bin';
$resize_settings['source_image'] = $sourceimage;
$resize_settings['maintain_ratio'] = false;
$resize_settings['quality'] = "100%";
$this->load->library('image_lib', $resize_settings);
令我惊讶的是,现在调整大小的过程需要更长时间:具体为15秒。
查看我的日志后,我发现每个调整大小操作都需要2秒,无论它调整大小的文件格式如何。我想这是因为我总是从原来的大小调整,这是非常大的。
我不想将调整大小过程卸载到预定的进程,因为这会降低网站的可用性。这意味着用户必须等待几分钟才能开始查看/使用图像。
那么,是否有任何智能方法可以大幅加快此调整大小过程,以便我可以实时保存它?请注意:允许较小的分辨率不是一种选择,这是我正在建立的摄影网站。另外,我真的需要提到的六种格式。
答案 0 :(得分:7)
作为一个想法,您可以将上传的大小调整为更合理的中间大小,然后将其作为进一步操作的基础。
或者,您可以执行ImageMagick的命令行版本,并使用Asynchronous shell exec in PHP中描述的过程在后台执行(至少大部分)图像转换。
最后,虽然它有点偏离主题,你是否允许纵向定位,或者这可能不是一个因素?
答案 1 :(得分:7)
好像你已经接受了答案,但我还是会发布我的。
首先,你真的不需要在质量上使用 100%, 90%或 85%值很好,同时减少你的处理时间和图像大小(如果你不相信我只是运行一些测试)。
我还使用this image和自定义JPEG()
函数完成了一些基准测试,第一个测试用例:
JPEG('./original.jpg', null, '1024*774', './output/large.jpg');
JPEG('./original.jpg', null, '500*378', './output/medium.jpg');
JPEG('./original.jpg', null, '240*161', './output/small.jpg');
JPEG('./original.jpg', null, '100*76', './output/thumb.jpg');
JPEG('./original.jpg', null, '50*38', './output/small_thumb.jpg');
JPEG('./original.jpg', null, '75*75', './output/square.jpg');
我的慢慢计算机平均需要60秒。
第二个测试用例:
JPEG('./original.jpg', null, '1024*774', './output/large.jpg');
JPEG('./output/large.jpg', null, '500*378', './output/medium.jpg');
JPEG('./output/medium.jpg', null, '240*161', './output/small.jpg');
JPEG('./output/medium.jpg', null, '100*76', './output/thumb.jpg');
JPEG('./output/medium.jpg', null, '50*38', './output/small_thumb.jpg');
JPEG('./output/medium.jpg', null, '75*75', './output/square.jpg');
这个“仅”16秒(我的电脑真的很慢ATM :P ),快了近4倍。
以下是JPEG()
功能,以防您想要制作自己的基准:
function JPEG($source, $crop = null, $scale = null, $destination = null)
{
$source = ImageCreateFromJPEG($source);
if (is_resource($source) === true)
{
$size = array(ImageSX($source), ImageSY($source));
if (isset($crop) === true)
{
$crop = array_filter(explode('/', $crop), 'is_numeric');
if (count($crop) == 2)
{
$crop = array($size[0] / $size[1], $crop[0] / $crop[1]);
if ($crop[0] > $crop[1])
{
$size[0] = $size[1] * $crop[1];
}
else if ($crop[0] < $crop[1])
{
$size[1] = $size[0] / $crop[1];
}
$crop = array(ImageSX($source) - $size[0], ImageSY($source) - $size[1]);
}
else
{
$crop = array(0, 0);
}
}
else
{
$crop = array(0, 0);
}
if (isset($scale) === true)
{
$scale = array_filter(explode('*', $scale), 'is_numeric');
if (count($scale) >= 1)
{
if (empty($scale[0]) === true)
{
$scale[0] = $scale[1] * $size[0] / $size[1];
}
else if (empty($scale[1]) === true)
{
$scale[1] = $scale[0] * $size[1] / $size[0];
}
}
else
{
$scale = array($size[0], $size[1]);
}
}
else
{
$scale = array($size[0], $size[1]);
}
$result = ImageCreateTrueColor($scale[0], $scale[1]);
if (is_resource($result) === true)
{
if (ImageCopyResampled($result, $source, 0, 0, $crop[0] / 2, $crop[1] / 2, $scale[0], $scale[1], $size[0], $size[1]) === true)
{
return ImageJPEG($result, $destination, 90);
}
}
}
return false;
}