zoukankan      html  css  js  c++  java
  • 【PHP】自有图片服务器,图片动态裁剪缩放

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


    完。

  • 相关阅读:
    Design and Implementation of the Sun Network File System
    Flash: An Efficient and Portable Web Server
    Java集合框架练习-计算表达式的值
    后缀数组专题训练
    经典问题-生产者和消费者问题
    ubuntu14.04下配置Java环境以及安装最新版本的eclipse
    Java多线程之CountDownLatch学习
    ZooKeerper学习之Watcher
    ZooKeeper之FastLeaderElection算法详解
    python获取当天日期进行格式转换
  • 原文地址:https://www.cnblogs.com/tujia/p/14677098.html
Copyright © 2011-2022 走看看