imageMagick

Linux nginx 下的配置说明

安装

首先,安装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

安装nginx时需添加 perl支持

# ./configure --with-http_perl_module --with-pcre
# make && make install

nginx配置
在http中加入以下配置:

perl_modules perl/lib;#perl/lib代表放置的perl脚本相对于nginx根目录的路径
perl_require xxx.pl;#xxx.pl代表所用到的脚本名称

在 请求的server中配置图片请求转发到perl处理 以equipone 测试服务器为例,在static配置的server中加入以下

 location ~ \.pl$ {
			perl pkg_name::process;
		  }

注:~ \.pl$表示以.pl结尾的图片请求转发到perl/lib 下的xxx.pl package为pkg_name名为process的方法处理

perl脚本的配置编写
下面编写perl脚本位置为nginx安装目录/usr/local/nginx +perl_modules配置目录 perl/lib 即:/usr/local/nginx/perl/lib/xxx.pl 编写pl需要引入模块(当然要求以安装的模块)以下面脚本为例

package showimg;
use nginx;
use Image::Magick;

use nginx 引入nginx模块就可以使用nginx中提供的perl语言接口, nginx 在perl中可以使用一下方法

$r->args – 请求的参数 .
$r->discard_request_body – 这个参数是让 Nginx 放弃 request 的 body 的内容.
$r->filename – 返回合适的请求文件的名字
$r->has_request_body(function) – 如果没有请求主体,返回0,但是如果请求主体存在,那么建立传递的函数并返回1,在程序的最后,nginx将调用指定的处理器.
$r->header_in(header) – 查找请求头的信息
$r->header_only – 如果我们只要返回一个响应的头
$r->header_out(header, value) – 设置响应的头
$r->internal_redirect(uri) – 使内部重定向到指定的URI,重定向仅在完成perl脚本后发生.可以使用 header_out(Location….的方法来让浏览器自己重定向
$r->print(args, …) – 发送数据给客户端
$r->request_body – 得到客户端提交过来的内容 (body 的参数,可能需要修改 nginx 的 client_body_buffer_size. )
$r->request_body_file —给客户的 body 存成文件,并返回文件名
$r->request_method — 得到请求 HTTP method.
$r->remote_addr – 得到客户端的 IP 地址.
$r->rflush – 立即传送数据给客户端
$r->sendfile(file [, displacement [, length ] ) – 传送给客户端指定文件的内容,可选的参数表明只传送数据的偏移量与长度,精确的传递仅在perl脚本执行完毕后生效.这可是所谓的高级功能啊
$r->send_http_header(type) – 添加一个回应的 http 头的信息
$r->sleep(milliseconds, handler) – 设置为请求在指定的时间使用指定的处理方法和停止处理,在此期间nginx将继续处理其他的请求,超过指定的时间后,nginx将运行安装的处理方法,注意你需要为处理方法通过一个reference,在处理器间转发数据你可以使用$r->variable().
$r->status(code) – 设置 http 的响应码
$r->unescape(text) – 使用 http 方法加密内容如 %XX
$r->uri – 得到请求的 URL.
$r->variable(name[, value]) – 设置变量的值

而imagemagick的perl接口可以到这里看  http://www.imagemagick.org/script/perl-magick.php 下面是imagemagick的一个简单的实现

$image= new Image::Magick;
$image->Read($real_file_path);
$image->Scale($size);
$image->Write($dest_file);
#$real_file_path指的是原始图片的路径如"/var/www/upload/client_static/logo.gif"
#$size指的是需要剪裁的长宽如"200x100"
#$dest_file指的是新生成图片的路径,如:"/var/www/upload/client_static/logo_200x100.gif",需路径目录需存在 否则会报错

脚本编写思路

完整的脚本编写思路为:

首先从nginx请求中获取索取参数 1,图片路径 2,剪裁大小;

然后利用imagemagick完成图片的剪裁;

最后将剪裁完成的文件流写入nginx的返回文件流中;

注:nginx中定义变量

可以在package中定义 our $xxx;表示package 下都可以使用

也可以在方法中定义 my $xxx;表示在此方法中使用

perl中join方法

join("aaa", "bbb", "ccc");

表示在bbb和ccc中加入aaa得到bbbaaaccc

附:完整的脚本代码

package showimg;

use nginx;
use Image::Magick;
our $image;

sub process {
    my $r = shift;

	 $r->send_http_header('Content-Type', 'image/gif');

	my $params = $r->args;

	if (!$params || ($params eq "")) {
	}

	@pairs = split(/&/, $params);
	foreach $pair (@pairs) {
		($name, $value) = split(/=/, $pair);
		$FORM{$name} = $value if ($name);
	}

	my $docroot = "/var/www/upload/client_static";
	my $url = $FORM{"url"};
	my $size = $FORM{"size"};
	my $real_file_path = join "", $docroot, $url;

 
	my @filename_tokens=split('\.', $url);

	my $ext=pop @filename_tokens;
	my $ini_file_name=pop @filename_tokens;
	my $dest_file=join("_resize_$size.", $ini_file_name, $ext);
	$dest_file=join "", $docroot, $dest_file;
 
	$image= new Image::Magick;
	$url_error = $image->Read($real_file_path);
	if ($url_error) {
		$dest_file=join("_resize_$size.", "/logo", "gif");
		$dest_file=join "", $docroot, $dest_file;
		$image->Read("$docroot/logo.gif");
	}
	$image->Scale($size);
	$image->Write($dest_file);
	$r->sendfile($dest_file);

	return OK;



}

1;
__END__

版本1.2
说明:1,修改剪裁后图片文件的路径:/var/www/tmp ,其他存放路径与图片真实路径一致;
如:原图路径为:/var/www/upload/client_static/2014/2014_01/2014_01_07/3/1/4/imageFile/1389075917555_A1.jpg 请求尺寸为155x159
那么请求时会创建一个新的图片存放为:/var/www/tmp/2014/2014_01/2014_01_07/3/1/4/imageFile/1389075917555_A1_resize_155x159.jpg
2,优化图片读取,当请求的图片以存在时直接读取,不再进行剪裁操作;

package showimg;

use nginx;
use Image::Magick;
our $image;
use   File::Path;

sub process {
    my $r = shift;

	 $r->send_http_header('Content-Type', 'image/gif');
	 #$r->send_http_header('text/html; charset=utf-8');

	my $params = $r->args;

	if (!$params || ($params eq "")) {
	}

	@pairs = split(/&/, $params);
	foreach $pair (@pairs) {
		($name, $value) = split(/=/, $pair);
		$FORM{$name} = $value if ($name);
	}

	my $docroot = "/var/www/upload/client_static";
	my $url = $FORM{"url"};
	my $size = $FORM{"size"};
	my $real_file_path = join "", $docroot, $url;

	##
	my $resizeRoot = "/var/www/tmp";
	my $pathIndex = rindex($url, "/");
	#my $ini_img_name = substr($url,$pathIndex+1);
	my $ini_img_path = substr($url,0,$pathIndex);
	my $comPath = join "", $resizeRoot, $ini_img_path;

 
	my @filename_tokens=split('\.', $url);

	my $ext=pop @filename_tokens;
	my $ini_file_name=pop @filename_tokens;
	my $dest_file=join("_resize_$size.", $ini_file_name, $ext);
	$dest_file=join "", $resizeRoot, $dest_file;
 
	$image= new Image::Magick;

	my $resurl_error = $image->Read($dest_file);
	if($resurl_error){
		my $url_error = $image->Read($real_file_path);
		if ($url_error) {
			$dest_file=join("_resize_$size.", "/logo", "gif");
			$dest_file=join "", $resizeRoot, $dest_file;
			$image->Read("$docroot/logo.gif");
		}

		if (-e $comPath){
		}else{
			eval{mkpath($comPath,0,0777)}; 
		}
		$image->Scale($size);
		$image->Write($dest_file);

	}
	$r->sendfile($dest_file);

	return OK;
}
1;
__END__

另一实例:

功能实现:通过nginx将图片请求转发到perl脚本交由imageMagic完成剪裁后返回数据流。
请求链接实例如下: static.alloysuppliers.info/content/ff808081163c05b001169d6655243ae9/thumbimages/pulpfiction24X36.jpg_size_100x100.resize

部署步骤:

1.测试服务器中安装nginx 与imageMagic nginx 需添加--with-http_perl_module --with-pcre模块 apt-get方式安装nginx可手动下载源码编译。

2.perl脚本添加:在nginx安装路径下/etc/nginx添加perl/lib文件夹加入showimg.pl脚本,代码下面展示;

3,nginx 配置文件中添加如下配置,将图片请求转发脚本处理。

注:生成的临时目录是:/var/www/tmp

location ~ \.resize$ {
		root /var/www/root;
		perl showimg::process;
		expires 1h;
	}

pl中获取图片地址与剪裁大小,处理生成符合大小的图片,并返回;showimg.pl代码如下:

package showimg;

use nginx;
use Image::Magick;
our $image;
use   File::Path;

sub process {
    my $r = shift;

	 $r->send_http_header('Content-Type', 'image/gif');
	 #$r->send_http_header('text/html; charset=utf-8');

	
	my $uri=$r->uri;
	my $url;
	my $sizeB;
	($url, $sizeB) = split(/_size_/, $uri);
	my $sizeIndex = rindex($sizeB, ".");
	my $size = substr($sizeB,0,$sizeIndex);

	my $docroot = "/var/www/root";
	my $real_file_path = join "", $docroot, $url;

	##
	my $resizeRoot = "/var/www/tmp";
	my $pathIndex = rindex($url, "/");
	#my $ini_img_name = substr($url,$pathIndex+1);
	my $ini_img_path = substr($url,0,$pathIndex);
	my $comPath = join "", $resizeRoot, $ini_img_path;

 
	my @filename_tokens=split('\.', $url);

	my $ext=pop @filename_tokens;
	my $ini_file_name=pop @filename_tokens;
	my $dest_file=join("_resize_$size.", $ini_file_name, $ext);
	$dest_file=join "", $resizeRoot, $dest_file;
 
	$image= new Image::Magick;

	my $resurl_error = $image->Read($dest_file);
	if($resurl_error){
		my $url_error = $image->Read($real_file_path);
		if ($url_error) {
			$dest_file=join("_resize_$size.", "/logo", "gif");
			$dest_file=join "", $resizeRoot, $dest_file;
			$image->Read("$docroot/logo.gif");
		}

		if (-e $comPath){
		}else{
			eval{mkpath($comPath,0,0777)}; 
		}
		$image->Scale($size);
		$image->Write($dest_file);

	}
	$r->sendfile($dest_file);

	return OK;



}

1;
__END__
posted @ 2014-03-13 14:25  china2k  阅读(527)  评论(0编辑  收藏  举报