zoukankan      html  css  js  c++  java
  • 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__
    
  • 相关阅读:
    计算1至n中数字X出现的次数
    DOM处理
    SQL Server中日志
    怎样玩转千万级别的数据
    协议的分用以及wireshark对协议的识别
    序列化json对象,通过ajax传入asp.net mvc后台
    新时代的Vim C++自动补全插件 clang_complete
    ASP.NET Web API 接口执行时间监控
    应用之星在线app开发平台,菜鸟也会做应用
    1.11 查找空值
  • 原文地址:https://www.cnblogs.com/china2k/p/3598517.html
Copyright © 2011-2022 走看看