function imagejpeg($image, $filename = null, $quality = null) { }
参数:
image
由图象创建函数(例如imagecreatetruecolor())返回的图象资源。
filename
文件保存的路径,如果未设置或为 NULL,将会直接输出原始图象流。
如果要省略这个参数而提供 quality 参数,使用NULL。
quality
quality 为可选项,范围从 0(最差质量,文件更小)到 100(最佳质量,文件最大)。默认为 IJG 默认的质量值(大约 75)。返回值:
成功时返回 TRUE, 或者在失败时返回 FALSE。
quality
参数可以调整图片的质量,以此来压缩图片,该参数的范围是0-100.
我一开始想到的是一直循环使用这个方法,同时检测文件大小,直到文件大小符合要求位置,可是遇到几个坑:
- 发现每次使用
filesize()
方法获取到的文件大小都一样,后来翻官方文档发现这样一段话:Note: 此函数的结果会被缓存。参见 clearstatcache() 以获得更多细节。
原来filesize()
方法的结果会缓存,使用clearstatcache()
函数可以清楚该缓存。 - 发现几个循环下来,得到的图片是被损坏的或者有马赛克模样的。分析后我认为是以下原因导致的:前一个保存图片的函数还没有结束,下一个保存图片的函数就已经执行了,导致图片损坏。
经过优化得到以下压缩图片到指定的KB的函数。算法原理:循环以一定的质量保存图片到一个临时文件,当图片大小小于或等于目标大小时跳出循环,获取图片文件大小前执行 clearstatcache()
函数,跳出循环后删除临时文件。临时文件名需各不相同,以免出现上面说的第二个问题。
原代码如下:
<?php
//把当前目录的test.jpg压缩到50kb
compressImage('./test.jpg', 50);
/**
* 压缩图片
*
* @param string $filename 图片文件路径
* @param int $maxFileSize 需要将图片压缩图片到最大多少KB
* @return int -1 压缩失败|0 未压缩|1 压缩成功
*/
function compressImage($filename, $maxFileSize = 150)
{
if (empty($filename) || $maxFileSize < 0 || !is_file($filename)) {
return 0;
}
clearstatcache(); //filesize函数的结果会被缓存,使用此函数清除文件状态缓存
$filesize = filesize($filename) / 1024; //filesize函数获得的是字节数,除以1024为KB数
if ($filesize <= $maxFileSize) {
return 0;
}
if ($filesize > 1024) {
$i = 80;
} elseif ($filesize > 500) {
$i = 90;
} else {
$i = 99;
}
$tempDir = "E:\\tmp\\"; //临时文件存放文件夹
if (!is_dir($tempDir)) { //文件夹不存在,创建
mkdir($tempDir);
}
$tmpFile = ''; //临时文件
$tmpFileList = []; //临时文件数组
do {
if ($i <= 0) {
return -1;
}
if ($filesize > 1024) {
$step = 5;
} elseif ($filesize > 500) {
$step = 3;
} else {
$step = 2;
}
$imageResource = getImageResources($filename); //获取图片文件资源
$tmpFile = $tempDir . uuid() . '.jpg'; //临时文件
imagejpeg($imageResource, $tmpFile, $i); //保存质量为$i的图片文件
imagedestroy($imageResource); //销毁图片资源
$tmpFileList[] = $tmpFile;
$i -= $step;
clearstatcache();
$filesize = filesize($tmpFile) / 1024;
echo $i . ' ' . $filesize . PHP_EOL;
} while ($filesize > $maxFileSize);
copy($tmpFile, $filename); //替换源图片
foreach ($tmpFileList as $tmpFile) { //删除临时文件
if (is_file($tmpFile)) {
@unlink($tmpFile);
}
}
return 1;
}
/**
* 获取图像资源
*
* @param $filename 图片路径
* @return null|resource 图片资源
*/
function getImageResources($filename)
{
$fileInfo = @getimagesize($filename);
$type = $fileInfo[2];
$imgResource = null;
switch ($type) {
case 1:
$imgResource = imagecreatefromgif($filename);
break; // GIF
case 2:
$imgResource = imagecreatefromjpeg($filename);
break; // JPG
case 3:
$imgResource = imagecreatefrompng($filename);
break; // PNG
}
return $imgResource;
}
/**
* 获取uuid
*
* @return string uuid
*/
function uuid()
{
return md5(time() . mt_rand(1, 10000));
}