本文链接: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


完。

 

相关文章: