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__

你可能感兴趣的:(ImageMagick)