PHP Imagick JPEG 优化
PHP Imagick JPEG Optimization
我正在使用 PHP Imagick
在运行时调整图像大小。该站点具有图像上传功能,我们不能相信用户使用网络友好 JPEGs
,因为在 mass-import
期间有许多 3
到 5MB
图像,甚至还有 13MB
大的几个。每张图片都变成缩略图 (200x200
),当从列表视图进入详细视图时,只显示一张图片,因此性能并不是什么大问题,尽管我们不能完全把它扔到一边。这是我们目前正在做的事情:
$iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if ($geometry['height'] > 1920 || $geometry['width'] > 1080) {
$iMagick->scaleImage(1920, 0);
if($geometry['height'] > $resizeHeight) {
$iMagick->scaleImage(0, 1080);
}
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->writeImage($file);
$Imagick->clear();
旁注:我刚刚意识到我的条件逻辑中关于 height/width 的缺陷,所以暂时忽略它。我会尽快编辑问题以反映正确的条件比较。对于那些没有注意到它的人,它会将所有图像缩放到 1920
宽,即使它应该缩放高度,然后在缩放后将其尺寸缩小到 1080 height
.
我用来测试的图像以 3MB 2398×2400
图像开始。将其缩放到 1079x1080
会生成 1.5MB
图像,然后添加 JPEG
压缩质量 70
将其降低到 750KB
。使用 kraken.io 可以将图像压缩到 60KB 以下。由于此脚本需要在运行时优化图像,因此我可以对其执行任何其他操作吗?
我已经阅读了使用已安装的 libjpeg 的建议,但我找不到任何关于它启用的功能或是否有强制 Imagick 专门使用它的方法的文档。我什至不确定 Imagick 是否已经在使用它。
编辑:解决方案
function itm_optimizeImage($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null]) {
$save = false;
$fi = new finfo(FILEINFO_MIME);
$mime = explode(';', $fi->file($file));
switch ($mime[0]) {
// possible to optimize other image types in the future
case 'image/jpeg':
try {
$iMagick = new Imagick($file);
if ($iMagick->getImageCompressionQuality() > $compression) {
$file = !itm_compressJPEG($file, $compression, $maxDimensions, $iMagick);
}
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
if ($file) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
}
$iMagick->clear();
break;
}
return $file;
}
function itm_compressJPEG($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null], &$iMagick = null) {
try {
$iMagickCreated = true;
if ($iMagick) $iMagickCreated = false;
else $iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if (($geometry['width'] / $maxDimensions['width']) > ($geometry['height'] / $maxDimensions['height'])) {
// scale by width
$iMagick->scaleImage($maxDimensions['width'], 0);
} else {
// scale by height
$iMagick->scaleImage(0, $maxDimensions['height']);
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->setImageFormat('jpg');
$iMagick->stripImage();
if ($iMagickCreated) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
$Imagick->clear();
}
return $file;
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
}
将 setImageCompressionQuality 的值设置为 70 并在其后添加这两行。
$image->setImageFormat("jpg");
$image->stripImage();
这将大大减小图像的大小。
我正在使用 PHP Imagick
在运行时调整图像大小。该站点具有图像上传功能,我们不能相信用户使用网络友好 JPEGs
,因为在 mass-import
期间有许多 3
到 5MB
图像,甚至还有 13MB
大的几个。每张图片都变成缩略图 (200x200
),当从列表视图进入详细视图时,只显示一张图片,因此性能并不是什么大问题,尽管我们不能完全把它扔到一边。这是我们目前正在做的事情:
$iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if ($geometry['height'] > 1920 || $geometry['width'] > 1080) {
$iMagick->scaleImage(1920, 0);
if($geometry['height'] > $resizeHeight) {
$iMagick->scaleImage(0, 1080);
}
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->writeImage($file);
$Imagick->clear();
旁注:我刚刚意识到我的条件逻辑中关于 height/width 的缺陷,所以暂时忽略它。我会尽快编辑问题以反映正确的条件比较。对于那些没有注意到它的人,它会将所有图像缩放到 1920
宽,即使它应该缩放高度,然后在缩放后将其尺寸缩小到 1080 height
.
我用来测试的图像以 3MB 2398×2400
图像开始。将其缩放到 1079x1080
会生成 1.5MB
图像,然后添加 JPEG
压缩质量 70
将其降低到 750KB
。使用 kraken.io 可以将图像压缩到 60KB 以下。由于此脚本需要在运行时优化图像,因此我可以对其执行任何其他操作吗?
我已经阅读了使用已安装的 libjpeg 的建议,但我找不到任何关于它启用的功能或是否有强制 Imagick 专门使用它的方法的文档。我什至不确定 Imagick 是否已经在使用它。
编辑:解决方案
function itm_optimizeImage($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null]) {
$save = false;
$fi = new finfo(FILEINFO_MIME);
$mime = explode(';', $fi->file($file));
switch ($mime[0]) {
// possible to optimize other image types in the future
case 'image/jpeg':
try {
$iMagick = new Imagick($file);
if ($iMagick->getImageCompressionQuality() > $compression) {
$file = !itm_compressJPEG($file, $compression, $maxDimensions, $iMagick);
}
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
if ($file) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
}
$iMagick->clear();
break;
}
return $file;
}
function itm_compressJPEG($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null], &$iMagick = null) {
try {
$iMagickCreated = true;
if ($iMagick) $iMagickCreated = false;
else $iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if (($geometry['width'] / $maxDimensions['width']) > ($geometry['height'] / $maxDimensions['height'])) {
// scale by width
$iMagick->scaleImage($maxDimensions['width'], 0);
} else {
// scale by height
$iMagick->scaleImage(0, $maxDimensions['height']);
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->setImageFormat('jpg');
$iMagick->stripImage();
if ($iMagickCreated) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
$Imagick->clear();
}
return $file;
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
}
将 setImageCompressionQuality 的值设置为 70 并在其后添加这两行。
$image->setImageFormat("jpg");
$image->stripImage();
这将大大减小图像的大小。