最近新入职了一家公司,技术老大要我开发一个可以读取多目录并压缩图片的功能,花了一点时间研究了一下,下面贴出来给大家分享一下,希望对大家有帮助
<?php
/**
* Created by PhpStorm.
*/
/*****
* 测试中出现了两个问题:
* 1.文件夹的资源过大(图片量过多,文件夹过多),会出现php内存溢出的报错 "out of memory",便捷解决方式①.在php.ini配置文件中修改memory_limit参数,但是修改的参数要合理。
* ②.动态设置在程序开始时ini_set('memory_limit','合理的内存大小');
* 2.文件夹、图片过多在程序运行的时候,会出现超时的情况。①.在php.ini配置文件中调整max_execution_time的参数值。②.动态设置在程序开始时set_time_limit(想要的时间值,不用单位(s));。
*****/
/**
* @param $oldFile 原图的带完整路径的文件名
* @param $newFile 压缩后图片完整路径的文件名
* @param int $type 1.等比例压缩 2.当原图宽度超过某个值的时候就进行比例计算得出对应比例的高度进行压缩
* @param int $compareWidth 原图片的宽度限制条件
* @param int $percent 压缩比例
* @return bool 图片失效返回false
*/
//重置php运行时的内存大小,一般在远程主机上是不能直接修改php.ini文件的,只能通过程序设置。注:在safe_mode(安全模式)下,ini_set失效,。
ini_set('memory_limit','1000M');
//设置程序运行的超市时间
set_time_limit(1200);
//忽略jpeg运行报出的警告
ini_set ('gd.jpeg_ignore_warning', 1);
function compress_image($oldFile,$newFile,$type=1,$percent=1,$compareWidth=0) {
//判断是否是伪造的图片文件类型
if (strpos($realType = mime_content_type($oldFile),'image/') === false) return false;
//获取图片信息
$testImg = getimagesize($oldFile);
//判断是否是有效图片
if (!$testImg) return false;
//图片信息赋给变量
list($width, $height, $type, $attr) = $testImg;
//原图片信息
$oldImageInfo = array(
'width'=>$width,
'height'=>$height,
'type'=>image_type_to_extension($type,false),
'attr'=>$attr
);
//创建一个原图的图像实例
$fun = "imagecreatefrom".$oldImageInfo['type'];
$oldImage = $fun($oldFile);
if ($type == 1 && in_array($type,[1,2])) {
$newWidth = $oldImageInfo['width']*$percent;
$newHeight = $oldImageInfo['height']*$percent;
}elseif($type == 2 && in_array($type ,[1,2])){
if ($oldImageInfo['width'] > compareWidth) {
$newWidth = compareWidth;
$newHeight = round(($newWidth*$oldImageInfo['height'])/$oldImageInfo['width'],1);
}
}else{
$newWidth = $oldImageInfo['width'];
$newHeight = $oldImageInfo['height'];
}
//根据新的长宽尺寸创建新的画布
$imageThump = imagecreatetruecolor($newWidth,$newHeight);
//将原图复制带图片载体上面,并且按照一定比例压缩,极大的保持了清晰度
imagecopyresampled($imageThump,$oldImage,0,0,0,0,$newWidth,$newHeight,$oldImageInfo['width'],$oldImageInfo['height']);
imagedestroy($oldImage);
$newImage = $imageThump;
//保存心创建的图片文件,由于与原文件同名,故可覆盖掉未压缩的原图
imagejpeg($newImage,$newFile);
imagedestroy($newImage);
}
/**
* @param $dir 需要被压缩图片的目标文件夹
* @return bool 非文件夹返回false
*/
function read_all ($dir){
//判断是否为一个$dir是否是一个文件夹
if(!is_dir($dir)) {
echo $dir."不是一个文件夹"."<br/>";
return false;
}
//打开目录句柄,返回一个资源集实例
$handle = opendir($dir);
//返回成功,则循环文件夹中的下一个目录或文件
if($handle){
while(($file = readdir($handle)) !== false){//读取失败会返回false,可能会返回等同于false的非布尔值,判断需要用全等(===)
//拼接读出来的目录组成全名
$temp = $dir.DIRECTORY_SEPARATOR.$file;
//如果不加 $file!='.' && $file != '..' 则会造成把$dir的父级目录也读取出来
if(is_dir($temp) && $file!='.' && $file != '..'){
//递归调用,继续循环出目录中的文件夹和文件
read_all($temp);
}else{
if($file!='.' && $file != '..'){
//图片压缩,并替换原图
compress_image($temp,$temp);
}
}
}
}
//资源流用完要及时记得关闭
closedir($handle);
}
//linux操作系统下文件目录为 斜杠‘/’
$src = getcwd().'\attachs\default\2018\11\15';//目标文件夹
read_all($src);
实测图片的大小如果有1M,可以被压缩9/10左右。
大家也可以自己封装一个类,这里我就不封装了!