使用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分
    <!DOCTYPE html>
<!--[if lt IE 7 ]><html class= 404 — 磨延城的博客 - 专注技术研究,分享生活体验

    步途坎坷,磨者独行,悠悠长歌觅知音.

    404: 好像迷路了...

    很抱歉,您要访问的页面迷路了,找不到了。您可以使用下边的搜索框进行搜索,也可以浏览你感兴趣的热门标签。