使用nginx或apache配合PHP按需生成缩略图

[文章作者:磨延城 转载请注明原文出处: https://mo2g.com/view/104/ ]

很早就了解到淘宝网在图片处理方面使用了缩略图动态实时生成的技术,解决了图片服务器集群海量存储的难题,有数据指出实时生成缩略图的模式比提前全部生成好缩略图的模式为淘宝网节约了90%的存储空间.又因为按需生成的模式可以生成任意尺寸的图片,这使得网页设计师可以更加灵活的创作.

很早就了解到淘宝网在图片处理方面使用了缩略图动态实时生成的技术,解决了图片服务器集群海量存储的难题,有数据指出实时生成缩略图的模式比提前全部生成好缩略图的模式为淘宝网节约了90%的存储空间。又因为按需生成的模式可以生成任意尺寸的图片,这使得网页设计师可以更加灵活的创作。

即便我们没有淘宝那么超前的架构技术,但是按需生成缩略图的思想还是可以借鉴的。在此,就跟大家分享一下,我是如果使用nginx(或者apache)配合PHP实现实时生成缩略图的。

先大致说明一下我们要实现的功能:访问连接地址http://xxx.com/resize/59-120-30.jpg,如果图片跟目录都不存在,就会在根目录创建文件夹resize,同时在该目录中生成图片59-120-30.jpg(宽:120px,高:30px),下回再访问http://xxx.com/resize/59-120-30.jpg,会直接返该图片。

1)网站根目录存在文件夹uploads,用于保存原图,其中存在图片59.jpg

2)网站根目录存在PHP文件resize.php,用于实时生成缩略图

3)开启nginx或apache的地址重写功能:当图片不存在,就把图片信息以get的方式传递给resize.php,并执行相关操作,如果图片存在,就直接返回图片。

nginx的重写规则如下:

location ~ .*\.(png|jpg)$ {
    if ( !-f $request_filename) {
        rewrite ^/(resize/.+-\d+-\d+\.(jpg|jpeg|png))$ /resize.php?file=$1 last;
    }
}

apache的重写规则如下:

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^/(resize/.+-\d+-\d+\.(jpg|jpeg|png))$ /resize.php?file=$1 [L]

resize.php的代码实现如下

<?php
if( isset($_GET['file']) ) {
    $path = trim($_GET['file']);//新图路径
    preg_match('#-\d+-\d+#',$path,$match);
    $srcPath = strtr($path,array($match[0]=>''));
    $srcPath = strtr($srcPath,array('resize'=>'uploads'));//原图路径

    if( is_file( $srcPath ) ) {
        $ext = strtolower( strrchr( $path , '.' ) );
        if( $ext == '.jpg' || $ext == '.jpeg') {
            header ( 'content-type:image/jpg' );
        } elseif( $ext == '.png' ) {
            header ( 'content-type:image/png' );
        } else {
            header('HTTP/1.1 404 Not Found');
        }
            
        $info = explode('-',$match[0]);
        $w = $info[1];
        $h = $info[2];
            
        $dir = dirname($path);
        if( !is_dir($dir) ) mkdir($dir,0755,true);
        /*
        这里改成自己的图片处理代码
        include 'imageModel.php';
        $imageModel = new imageModel();
        $imageModel->resize($srcPath,$path,array($w,$h));
        */
        echo file_get_contents($path);
        exit;
    }
}
header('HTTP/1.1 404 Not Found');

这样,就实现了动态实时生成缩略图的功能。

在我负责维护公司的网站之前,打开网站首页图片就要花费8MB的数据量,因为出现了太多类似25x25像素的img标签加载了800x800图片的情况!而腾讯首页才耗费1MB的数据量,淘宝的全部加载完毕也才2MB。后来使用了我这套方案,首页只需要2MB的数据流量,再添加上图片按需加载的机制,网站快了很多。等空闲了,再做一下CDN加速,保证网站能飞起来!

其实上边的代码,还可以强化一下,防止生成不需要的尺寸的图片。可以定义一个数组,存储合法的图片尺寸,示例如下:

$wh = array(
    array(120,30),
    array(220,60),
);
if( in_array(array($w,$h),$wh) ) {
    //如果图片尺寸被定义
    //才执行自己的图片处理代码
}


    评论:

    1. mo2g 回复2014年05月05日 23时01分
      磨者
      新博文发表之后不能马上在博客栏目显示,之间好像有延时,时间还不短

    2. 磨延城 回复2014年05月06日 19时54分

      呵呵,这都被你发现了。以前考虑了搜索引擎的收录跟仿采集之类的问题,所以做了点延迟处理,以后会调回来的

    3. ghostry 回复2015年03月21日 13时05分
      磨者
      有没有办法不用url传值得到<img>里边设定的值

    4. 我来说两句:

        切换  

      磨途歌检测发现,您当前使用的浏览器版本过低,要想使用画板模式,请先更新浏览器

        切换  

      磨途歌随机验证码