• 《转》使用nginx和php实时产生缩略图


    在做自动静态化的时候,突然想到下面这个场景,也给出了解决方法。亲,真的很实用,耐心看下去。
     
     
    当我从后台上传一个截图之后,480*800的截图之后,当时就没有压缩出320*480的小缩略图。好吧,服务器轮询一下,全部产生出320*480的图片。
    那下一次呢,又有160*240的图片了,又轮询吗,费时费力,还不能马上就得到小图。这个时候,我们就要开始抱怨了,怎么要这么多种图片啊,设计师,你就不能老早就想好要哪些图片么?
     
    其实,nginx是一个强大的反向代理服务器,通过它的rewrite模块,我们可以实现自动产生缩略图,也不用轮询数据库了。产品设计,要什么尺寸的,客户端直接通过某种规则访问就是了,我马上就产生给你。
    而且,后台上传的时候,只要保存一张最大的图片就ok了。
    这样的话,需要其他尺寸的图片,仅仅修改客户端的访问方式即可。
     
    标签: Nginx PHP
     

    代码片段(4)[全屏查看所有代码]

    1. [代码]Nginx     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #假设,服务器上面有一个文件:abc.jpg,通过http://filefs.domain.com/file/abc.jpg能够访问到原图。其#实一般的,我们在数据库里面也就保存了“/file/abc.jpg”这部分内容。
    #现在,我们要实现通过http://filefs.domain.com/file/abc.jpg.w320.jpg由服务器自动产生#abc.jpg.w320.jpg(w320,320px的宽度)这个缩略图。并返回图片数据。
    #要满足以下两个条件:
    #   1.如果abc.jpg.w320.jpg存在,则不重新产生图片
    #   2.如果不存在,则在同一次的请求中,返回图片数据,和保存图片文件到服务器。
     
     
    server {
        listen       80;
        server_name  filefs.domain.com;
         
        root /var/www/http/filefs.domain.com;
        location / {
            index  index.html index.htm;
        }
         
        location ~ .(png|jpg|jpeg|gif)$ {
            #如果文件不存在,则rewrite到产生图片的脚本文件autoimg.php
            if (!-f $request_filename) {
                rewrite ^/.*$ /autoimg.php;
                expires max;
            }
            #如果文件存在,则设置过期时间,关闭访问日志
            if ( -f $request_filename ) {
                expires max;
                access_log off;
            }
        }
         
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
         
        location ~ autoimg.php$ {#安全性考虑,文件服务器,只这个脚本文件的范围提交给php处理
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/http/filefs.domain.com$fastcgi_script_name;
            include        /usr/local/nginx/conf/fastcgi_params;
        }
    }

    2. [代码]php产生图片文件     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    <?php
        $file = $_SERVER ['REQUEST_URI'];//请求字串 /file/abc.jpg.w320.jpg
        $desfile = $_SERVER ['DOCUMENT_ROOT'] . $file; //目标目标路径 /var/www/http/file/abc.jpg.w320.jpg
        $dirname = dirname ( $desfile ) . "/";
        $filename = basename ( $desfile );
        if (preg_match ( "/([^.]+.(png|jpg|jpeg|gif)).w([d]+).(jpg)/i", $filename, $m )) {
            $srcfile = $dirname . $m [1];
            $width = $m [3];                    //匹配出输出文件宽度
            if (in_array ( $width, array (      //只产生202和320宽度的文件
                    202,
                    320
            ) ) && file_exists ( $srcfile )) {  //而且文件不存在
                thumbnail ( $srcfile, $desfile, $width );
            }
        }
         
        /**
         * 生成缩略图
         *
         * @param 源 $src           
         * @param 缩放后的宽带 $width        
         *
         */
        function thumbnail($src, $des, $width) {
            ob_start ();//开始截获输出流
            $imageinfos = getimagesize ( $src );
            $ext = strtolower ( pathinfo ( $src, 4 ) );
            if ($imageinfos [2] == 1) {
                $im = imagecreatefromgif ( $src );
            } elseif ($imageinfos [2] == 2) {
                $im = imagecreatefromjpeg ( $src );
            } elseif ($imageinfos [2] == 3) {
                $im = imagecreatefrompng ( $src );
            }
             
            if (isset ( $im )) {
                $height = $imageinfos [1] * $width / $imageinfos [0];
                $dst_img = ImageCreateTrueColor ( $width, $height );
                 
                imagesavealpha ( $dst_img, true );
                $trans_colour = imagecolorallocatealpha ( $dst_img, 0, 0, 0, 127 );
                imagefill ( $dst_img, 0, 0, $trans_colour );
                 
                imagecopyresampled ( $dst_img, $im, 0, 0, 0, 0, $width, $height, $imageinfos [0], $imageinfos [1] );
                 
                header ( 'content-type:image/jpg' );
                imagejpeg ( $dst_img, null, 90 );//输出文件流,90--压缩质量,100表示最高质量。
                 
                @imagedestroy ( $im );
                @imagedestroy ( $dst_img );
            } else {
                echo @file_get_contents ( $src );
            }
            $content = ob_get_contents ();//获取输出流
            ob_end_flush ();//输出流到网页,保证第一次请求也有图片数据放回
            @file_put_contents ( $des, $content );//保存文件
        }
    ?>

    3. [图片] QQ截图20120606104850.png    

    4. [图片] QQ截图20120606104908.png    



    开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

    发表评论 回到顶部网友评论(15)

    • 1楼:开源中国首席大爷 发表于 2012-06-06 11:44 回复此评论
      还好,但是需要修改不少模板文件,也并不算太方便的 
       
    • 2楼:还没有名字 发表于 2012-06-06 12:27 回复此评论
      比较实用
       
    • 3楼:SimonXia 发表于 2012-06-06 15:50 回复此评论

      引用来自“wwwxxxfr”的评论

      还好,但是需要修改不少模板文件,也并不算太方便的 
      这最可取的地方是: 1.后台上传的时候,不要预产生一系列的不同大小的图片.预产生的图片,可能90%是没有用处的. 2.更改UI的时候,可以任意产生你需要的大小的图片.比较灵活,不用轮询数据库,将所有图片都压缩一遍.
       
    • 4楼:pjiaxu.com 发表于 2012-06-09 20:31 回复此评论
      这个牛X,学习了。
       
    • 5楼:cevin 发表于 2012-06-17 01:26 回复此评论
      +1
       
    • 6楼:HDR 发表于 2012-06-20 16:05 回复此评论

      引用来自“SimonXia”的评论

      引用来自“wwwxxxfr”的评论

      还好,但是需要修改不少模板文件,也并不算太方便的 
      这最可取的地方是: 1.后台上传的时候,不要预产生一系列的不同大小的图片.预产生的图片,可能90%是没有用处的. 2.更改UI的时候,可以任意产生你需要的大小的图片.比较灵活,不用轮询数据库,将所有图片都压缩一遍.
      这种方法很实用。以前也有过类似的想法,可惜一直没有去做
       
    • 7楼:廿九 发表于 2012-06-21 10:33 回复此评论
      支持一下
       
    • 8楼:童冠 发表于 2012-06-28 12:43 回复此评论
       
    • 9楼:moqidian 发表于 2012-08-06 16:11 回复此评论
      好东西
       
    • 10楼:阿城守候 发表于 2013-01-29 14:23 回复此评论
      能不能截服务器屏幕的图,效果跟主机屋的VPS一样捏
       
       
    • 11楼:蚂蚁浩 发表于 2013-03-20 16:38 回复此评论
      最好处理服务器和图片的服务器能分开会比较好 ,另外用php处理我总觉得太笨了 呵呵
       
    • 12楼:wooops 发表于 2013-03-25 00:53 回复此评论

      引用来自“蚂蚁浩”的评论

      最好处理服务器和图片的服务器能分开会比较好 ,另外用php处理我总觉得太笨了 呵呵
      有什么好办法?
       
    • 13楼:蚂蚁浩 发表于 2013-03-25 14:26 回复此评论

      引用来自“wooops”的评论

      引用来自“蚂蚁浩”的评论

      最好处理服务器和图片的服务器能分开会比较好 ,另外用php处理我总觉得太笨了 呵呵
      有什么好办法?
      前台一个nginx 后台一台nginx 前台遇到缩率图请求 使用proxy转发到后台nginx 用filter 处理, 同时在前台做缓存,这样对后台服务器的要求不会很高. 而且也相当灵活
       
    • 14楼:oopul 发表于 2013-08-24 11:04 回复此评论
      Nginx+Nginx Image Thumb Module  http://www.oschina.net/p/ngx_image_thumb
       
    • 15楼:H_Charles 发表于 2014-08-11 17:07 回复此评论
      好想法
  • 相关阅读:
    用Lua编写ACM算法竞赛开灯问题
    糟糕的中文版龙书
    font and face, 浅探Emacs字体选择机制及部分记录
    栈与卡特兰数
    关于2018年东南大学Robomaster算法组工作的总结
    C++中的默认参数规则
    MySQL第三章——嵌套查询
    MySQL第三章——空值的处理
    MySQL第三章——数据更新
    MySQL第三章——连接查询
  • 原文地址:https://www.cnblogs.com/sanwenyu/p/4564251.html
Copyright © 2020-2023  润新知