本文章已被更新,强烈推荐采用此《高性能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; } }
好滴,到这里你可以尽情的使用动态裁剪图片方案了。你如果有什么更好的想法和建议,欢迎@我。我在国外还发现了一篇比较不错的文章,如果你有此需求也可以借鉴。