高性能PHP图片动态裁剪方案

本文章已被更新,强烈推荐采用此《高性能PHP图片动态裁剪方案2》文章所述方法进行图片裁剪。2014-03-04

大家先看效果:

80×80

100×100

原图

注意查看URL链接,后面的参数就是实际生成的图片尺寸大小。

我在生产环境中有遇到这样的一种情况,前端美工设计出来的页面,图片尺寸不一的时候(这种情况的出现证明管理不好),后端程序已经在运行了,修改代码貌似不是最优办法。可是通过前端的JS或者使用width、height硬性缩放,一来带给用户体验不佳,二来增加了服务器带宽的压力。所以为了解决这样的一个问题,我理解还是做一个动态生成图片尺寸的解决方案,我还是依然使用PHP作为后台支撑。

我们用到的程序你可以在这里下载下来,其实你会发现很多时候github上面优秀的程序绝对不是盖的。

下载下来解压缩的过程我就不赘述了,直接放到你的网站虚拟目录下面,比如我在/home/webroot/img1里面,当你看到我上面的地址的时候我已经是做了伪静态处理,后面再说。

我修改了phpthumb程序中的examples文件夹下的resize_adaptive.php文件,贴出代码,我按照个人需要修改的,你也可以自定义。

resize_adaptive.php

<?php
define ( 'X_FILE1', '/home/webroot/img1/uploads/' );
define ( 'X_FILE2', '/home/webroot/mysite/uploads/' );
require_once '../ThumbLib.inc.php';

$f = base64_decode ( $_GET ['f'] );
$type = $_GET ['t'];
$w = $_GET ['w'];
$h = $_GET ['h'];

$path = '';
if ($type == 'z') {
  $path = X_FILE1;
} elseif ($type == 'm') {
  $path = X_FILE2;
} else {
  die ( 'api error!' );
}

if (! file_exists ( $path . $f )) {
  header ( "HTTP/1.0 404 Not Found" );
  die ();
}

$thumb = PhpThumbFactory::create ( $path . $f );
if ($w != '' && $h != '') {
  $thumb->adaptiveResize ( $w, $h );
}

$thumb->show ();

 

具体的我就不解释了,为了便于方面寻找路径将路径进行base64转码,然后生成图片。但是我们都知道对于这种动态生成的图片肯定会影响到服务器性能,所以我们要使用缓存,将动态生成的图片进行缓存起来,有了就不再去访问php了直接从缓存中读取,这个在nginx上配置是十分简单且有效的。当然我在生产环境中已经启用了CDN,这无疑是最优的办法了。如果没有使用CDN用nginx自带的缓存也是可以的,性能上面和以绝对路径拿图片没有什么差别的。

我贴出我的nginx配置文件,大家可以参考下。

img.conf

#nginx缓存生成的文件夹目标   最大30G  1分钟无人访问 自动删除
proxy_cache_path /home/caches/nginx/ levels=1:2 keys_zone=Z:10m inactive=1m max_size=30g;

#代理8331端口
server {
        listen       80;
        server_name img1.nnjiaju.com;
        error_page   404 403 402 500 502 503 504  /404.html;
        location = /404.html {
        }

        location / {
            expires 30d;
            proxy_cache Z;
            proxy_cache_valid 200 30m;
			proxy_redirect          off;
			proxy_set_header        Host $host;
			proxy_set_header        X-Real-IP $remote_addr;
			proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
			client_max_body_size    100m;
			client_body_buffer_size 256k;
			proxy_connect_timeout   60;
			proxy_send_timeout      60;
			proxy_read_timeout      60;
			proxy_buffer_size       512k;
			proxy_buffers           512k;
			proxy_busy_buffers_size 512k;
			proxy_temp_file_write_size 512k;

            if ( !-e $request_filename) {
                proxy_pass  http://127.0.0.1:8331;
            }
        }
}

#这个服务器真实处理php裁剪
server {
        listen       8331;
        root   /home/webroot/img1;
        index  index.php;

        access_log  logs/access.nnjiaju_img1.log;
        error_log logs/error.nnjiaju_img1.log;

        error_page   404 403 402 500 502 503 504  /404.html;
        location = /404.html {
        }

        location / {
				#这里让url变得漂亮,就是你上面看到效果的例子
				#匹配带尺寸参数
                rewrite ^([^\.]*)/d/(\w+)/(\w+\=*)_([0-9]+)x([0-9]+)\.jpg$ $1/thumb/examples/resize_adaptive.php?t=$2&f=$3&w=$4&h=$5 last;
				#只看原图
                rewrite ^([^\.]*)/d/(\w+)/(\w+\=*)\.jpg$ $1/thumb/examples/resize_adaptive.php?t=$2&f=$3 last;
                if (!-e $request_filename) {
                        return 404;
                }
        }

		#运行PHP标准写法
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

    }

好滴,到这里你可以尽情的使用动态裁剪图片方案了。你如果有什么更好的想法和建议,欢迎@我。我在国外还发现了一篇比较不错的文章,如果你有此需求也可以借鉴。

作者:Yinchiang

i'm X

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

评论审核已启用。您的评论可能需要一段时间后才能被显示。