摘要:
nginx内嵌Perl脚本实现缩略图生成
安装所需软件
安装ImageMagick及Perl Imager:
# yum install ImageMagick ImageMagick-perl...
-
安装所需软件
安装ImageMagick及Perl Imager:
# yum install ImageMagick ImageMagick-perl perl-YAML
# yum install giflib-devel libjpeg-devel libtiff-devel libpng-devel freetype-devel
# cpan -i Imager
查看当前支持的图片格式:
# perl -MImager -e 'print join "\n", sort keys %Imager::formats'
安装nginx(启用HttpPerlModule):
# ./configure --with-http_perl_module --with-pcre
# make && make install
-
nginx配置例子:
[root@centos191 lib]# cat /usr/local/nginx/conf/nginx.conf
...
perl_modules perl/lib;
perl_require resizer.pm;
server {
listen 80;
server_name images.;
root /data/www/qingluobo;
index index.html;
#error_page 404 /404.html;
location /img {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^(.*)(.jpg|.JPG|.gif|.GIF|.png|.PNG)$ /scale$1$2 last;
}
location /scale {
internal;
perl resize::handler;
}
}
...
-
Perl脚本
Perl脚本例子:
# mkdir -p /usr/local/nginx/perl/lib
# cd /usr/local/nginx/perl/lib
# cat resizer.pm
package resize;
use nginx;
use Image::Magick;
our $base_dir="/data/www/qingluobo";
our $image;
sub handler {
my $r = shift;
return DECLINED unless $r->uri =~ m/\.thumb\.\d{1,}?x\d{1,}?\./;
my $uri=$r->uri;
$uri=~ s!^/scale!!;
my $dest_file="$base_dir/$uri";
my @path_tokens=split("/", $uri);
my $filename=pop @path_tokens;
my @filename_tokens=split('\.', $filename);
# We know the last part is the extension;
# We know the one before that is the dimensions
# We know that the one before that is the resize_to string
my $ext=pop @filename_tokens;
my $dimensions=pop @filename_tokens;
pop @filename_tokens;
$filename=join('.', @filename_tokens, $ext);
my $real_file_path=join("/", $base_dir, @path_tokens, $filename);
return DECLINED unless -f $real_file_path;
my ($width,$height)=split("x", $dimensions);
if ($height<1) {
$dimensions=$width;
}
$image= new Image::Magick;
$image->Read($real_file_path);
$image->Scale($dimensions);
$image->Write($dest_file);
$r->sendfile($dest_file);
return OK;
}
1;
__END__
-
访问测试
原图:http://images./img/test.jpg
缩略图1:http://images./img/test.thumb.400×400.jpg
缩略图2:http://images./img/test.thumb.600×0.jpg
php脚本实现缩略图生成
-
nginx配置例子:
server {
listen 80;
server_name images.;
root /data/www/qingluobo;
index index.html index.php;
#error_page 404 /404.html;
location ~ ^/thumbs/(.*) {
try_files $uri @resize;
expires 4h;
}
location @resize {
internal;
rewrite ^(?:.*)(?:.jpg|.JPG|.gif|.GIF|.png|.PNG)$ /resize.php?ReqURI=$uri last;
}
location = /resize.php {
internal;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
}
-
需要安装php扩展imagick.
php脚本例子:
<?php
if ( empty($_GET['ReqURI']) ) {
exit('Invalid Param for ReqURI');
}
$uri = $_GET['ReqURI'];
// whether to allow creating new directory
$locked_dir_creation = false;
$source_path = dirname(str_replace('/thumbs', '',$uri));
$base_dir = "/data/www/qingluobo";
$path_tokens = explode('/', $uri);
$filename = array_pop($path_tokens);
if ( !preg_match('/(.*)_(\d+)x(\d+)_([1-3])\.(jpe?g|png|gif)/i', $filename, $matches) ){
header("Status: 404 Not Found");
echo 'invalid filename :' . $filename;
exit;
}
$source_file = $base_dir . $source_path . '/' . $matches[1];
if ( !is_file($source_file) ) {
header("Status: 404 Not Found");
echo $filename . ' Not Found';
exit;
}
$dest_path = $base_dir . implode('/', $path_tokens);
if ( !is_dir($dest_path) && $locked_dir_creation ) {
header('Status: 403 Forbidden');
echo 'Directory creation is forbidden.';
exit;
}
$new_width = $target_width = $matches[2];
$new_height = $target_height = $matches[3];
$mode = $matches[4];
$target_format = strtolower($matches[5]);
$source_img = new Imagick($source_file);
$dimension = $source_img->getImageGeometry();
$orig_width = $dimension['width'];
$orig_height = $dimension['height'];
switch ($mode) {
case '1':
break;
case '2':
/*preserve aspect ratio, resize the image to specified box,
resized image will be of specified dimension or smaller */
$new_height = $orig_height * $new_width / $orig_width;
if ($new_height > $target_height) {
$new_width = $orig_width * $target_height / $orig_height;
$new_height = $target_height;
}
break;
case '3':
/*zoom and crop the image to fill the specified dimension*/
// crop to get desired aspect ration
$desired_aspect = $target_width / $target_height;
$orig_aspect = $orig_width / $orig_height;
if ($desired_aspect > $orig_aspect) {
$trim = $orig_height - ($orig_width / $desired_aspect);
$source_img->cropImage($orig_width, $orig_height-$tirm, 0, $trim /2);
} else {
$trim = $orig_width - ($orig_height * $desired_aspect);
$source_img->cropImage($orig_width-$trim, $orig_height, $trim/2, 0);
}
break;
}
/* default mode 1, stretch image to fit the specified dimensions without preserving aspect ratio */
$source_img->resizeImage($new_width, $new_height, imagick::FILTER_LANCZOS, 1);
if ( !is_dir($dest_path) && !mkdir($dest_path, 0755, true) ) {
echo 'cannot create dir : ' . $dest_path;
exit;
}
$dest_file = $dest_path . '/' . $matches[0];
//file_put_contents($dest_file, $source_img);
clearstatcache($dest_path);
$source_img->writeImage($dest_file);
header("Content-Type: image/$target_format");
echo $source_img;
-
访问测试
原图:http://images./img/test.jpg
缩略图(mode 1):http://images./thumbs/img/test.jpg_300x300_1.jpg
缩略图(mode 2):http://images./thumbs/img/test.jpg_300x300_2.jpg
缩略图(mode 3):http://images./thumbs/img/test.jpg_300x300_3.jpg
|