本文链接:https://www.cnblogs.com/tujia/p/14677098.html
背景:
1)几年前的PHP老项目,没用使用OSS来保存图片,而是用了一台独立的服务器来放图片。
2)但因为后台没有限制图片上传的大小,经营人员也没有手动裁剪图片,导致图片的尺寸很大,前端加载很慢,影响用户体验,也浪费带宽。
3)所以,我想着能不能改造一下图片服务器,像阿里云OSS那样,显示的时候,在url增加一个参数,就能动态裁剪(缩放)输出。
一、闲话少说,直接上代码吧(图片服务器根目录增加一个 crop.php 文件)
<?php /** * @Author Tiac * @DateTime 2021-04-16 * @Description 图片裁剪 * @see https://www.cnblogs.com/tujia/p/14677098.html */ error_reporting(E_ALL); ini_set('display_errors', 'On'); define('ROOT', str_replace('\', '/', __DIR__)); $img = isset($_GET['img'])? trim($_GET['img']):''; $w = isset($_GET['w'])? intval($_GET['w']):''; $h = isset($_GET['h'])? intval($_GET['h']):''; if (empty($img) || !file_exists(ROOT . $img)) { header('HTTP/1.1 404 Not Found'); header("status: 404 Not Found"); exit; } $src = ROOT . $img; // CDN缓存 header('Cache-Control: max-age=604800'); if (function_exists('mime_content_type')) { $mime = mime_content_type($src); } elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME); $info = finfo_file($finfo, $src); finfo_close($finfo); list($mime, $charset) = explode('; ', $info); } else { $parts = pathinfo($src); $extension = strtolower($parts['extension']); $mime = 'image/' . ($extension=='jpg'?'jpeg':$extension); } header('Content-Type: ' . $mime); // 没设置宽高的,直接输出 if ($w == 0 && $h == 0) { echo file_get_contents($src); exit; } switch($mime) { case 'image/jpeg': $img_r = imagecreatefromjpeg($src); break; case 'image/png': $img_r = imagecreatefrompng($src); break; case 'image/gif': $img_r = imagecreatefromgif($src); break; case 'image/webp': $img_r = imagecreatefromwbmp($src); break; } list($width, $height, $type, $attr) = getimagesize($src); if ($w > 0 && $h > 0) { $minw = intval($width / $height * $h); $minh = intval($height / $width * $w); $w > $minw && $w = $minw; $h > $minh && $h = $minh; } else { $w == 0 && $w = intval($width / $height * $h); $h == 0 && $h = intval($height / $width * $w); } $dst_r = ImageCreateTrueColor($w, $h); $result = imagecopyresampled( $dst_r, $img_r, 0, 0, 0, 0, $w, $h, $width, $height ); if ($result === true) { switch($mime) { case 'image/jpeg': imagejpeg($dst_r, null, 100); break; case 'image/png': imagepng($dst_r); break; case 'image/gif': imagegif($dst_r); break; case 'image/webp': imagewebp($dst_r); break; } } else { die('wrong.'); }
注:
1)创建好crop.php之后,就可以直接用 https://img.xxx.com/crop.php?img=/article/202103/31/161717171088039.jpg&w=500 这种url形式来动态缩放图片了;
2)但为了美观及小改动原代码,还需要增加一个rewrite规则;
3)服务器记得要打开 php_fileinfo 扩展。
二、增加一个 nginx rewrite 规则
if ($query_string ~ [wh]=d+) { rewrite ^([^?]+)(.*) /crop.php?img=$1 last; }
注:这里是判断query_string里有 w= 或 h= 关键字时才重写url,如果你的图片服务器url有冲突,那这个if条件你得改改。
三、最终url示例
https://img.xxx.com/article/202103/31/161717171088039.jpg?w=200&h=200
https://img.xxx.com/article/202103/31/161717171088039.jpg?w=500
https://img.xxx.com/article/202103/31/161717171088039.jpg?h=200
注:我只弄了等比例缩放,所以同时填了w和h参数时,会自动约束计算最小的宽和高,等比例缩放;如果想要强制拉抻图片效果的,改一下代码就可以了
本文链接:https://www.cnblogs.com/tujia/p/14677098.html
完。