本篇文章给大家介绍一下nodejs+udp实现图片裁剪功能的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
相关推荐:《nodejs 教程》
说起来udp,可能最吸引人的就是【udp服务器】了吧。
udp服务器可以用于一些特殊数据的(高效)传输,例如图片、视频和音频信息等
我见过一些大佬用udp来和c++ server交互,主要目的就是希望将php无法处理的逻辑业务,通过udp服务器发送给其他server来处理。
所以,能不能有这样一个需求:我们有两个服务器a、b,我们希望a处理所有的业务逻辑,而b只去做数据库操作(比如更新)。
有多个设计思想可以解决上面的问题,最简单的就是通过http发送请求的方式,将a处理后的参数通过http方式传递给b服务器,然后b服务器获取参数后更新数据库。 —— 这种方式对于node.js 来说非常简单,但是http是一个tcp协议,对于我们自己的两台可信赖的服务器,我们更希望使用udp来传送协议,避免tcp中不必要的数据传输。
接下来我们要介绍的一个应用,就是使用node.js来处理图片上传切割(图片处理),并通过客户端显示所有的经过处理后的图片列表,而这个功能也将应用udp模块来实现。
应用分析本应用包含两个部分,一个是图片上传的web服务功能模块、图片处理后的页面展示功能;另外一个则是图片的处理,主要是图片的切割保存。而作为用户,希望是这样的一个工具,上传一个图片,并指定其需要切割的长和宽,通过系统处理后返回给用户一个切割好的图片,并通过页面返回展示。
根据以上的需求的分析,我们将上面的需求转化为如图4-5所示的系统运行流程图。根据应用的分析,我们会设计两个服务器,一一个是web服务器,另外一个则是图片处理服务器,两者通过udp协议进行交互:
图片上传页面,主要是图片的上传和预览功能页面;图片展示页面,展示通过图片处理后返回的图片; http web服务器主要的作用是文件上传和图片展示;图片处理服务器,将web服务器的数据通过udp协议传递给图片处理服务器,图片处理服务器做-定的处理后返回相应的数据到web服务器。
udp server端实现 —— 图片处理服务器根据上面的分析,本应用需要实现的3个功能模块分别是,udp server端、udp client端(web server) 和jade页面。
那么首先我们从该应用的udpserver端代码实现原理开始介绍(也就是图片处理服务器)。图片处理服务器作为udp的server端,要应用udp模块实现udp server, 由于该udp server依赖图片处理工具,因此在udp服务程序中会应用github中的一个开源node.js图片处理工具一node -imagemagick来辅助实现图片处理功能。根据上面的分析,我们简单设计出udp server的代码框架,代码如下:
const dgram=require('dgram'); //udpconst server=dgram.createsocket(udp4);server.on(message,function(msg,rinfo){ //监听消息事件后处理})server.on(listening,function(){ var address=server.address(); console.log(server listening +address.address+:+address.port);})server.bind(监听端口号);
会发现,udp其实似乎和socket.io差不多?都是采用的监听消息流机制。而http没有这样做,所以几乎不用http去做这些高交互的事情 —— 这固然和他们的内部实现有关。
监听完了,该干正事了:我们需要一个函数去处理图片。这个函数的触发时间要在事件流之后:
npm install imagemagick
需要注意的是,在使用该工具时,必须安装imagemagick-cli系统工具软件:sudo apt-get install imagemagick --fix-missing(否则会在运行期间抛出异常)
/** url:图片源路径 width:图片压缩宽 height:图片压缩高 newname:图片处理后存储路径**/function resizeimage(url,width,height,newname,callback){ var im=require('imagemagick'); im.resize({ srcpath: url, dstpath: newname, width: width, height: height }, function(err,stdout,stderr){ if(err){ callback(-1); }else{ callback(stdout); } })}
然后在udp的onmessage回调函数中调用:
server.on(message,function(msg,rinfo){ var imageobject=json.parse(msg); resizeimage(imageobject.url, imageobject.width, imageobject.height, imageobject.new_name, function(ret){ var retjson; if(ret==-1){ retjson={'code':-1,'msg':'some error in resize image','data':{}} }else{ retjson={'code':0,'msg':'success','data':{'name':imageobject.new_name}} } //将json对象转为json字符串 var retstr=json.stringify(retjson); //转为buffer对象,用于udp传输 var message=new buffer(retstr); server.send(message,0,message.length,rinfo.port,rinfo.address); })})
server.on(message,callback(msg, rinfo))回调函数中有msg和rinfo参数,其中msg为客户端发送的消息数据,而rinfo则为客户端信息,服务器端根据客户端信息中的端口port和ip地址address, 应用server.send响应数据到客户端即可。到这里我们就实现了一个图片处理的udp服务器,接下来介绍web服务器端是如何与其交互的。
udp client端 —— 前台服务器npm install express jade formidable body-parser
const jade=require('jade');const express=require('express');const bodyparser=require('body-parser');const fs=require('fs');const view=__dirname+/view/;var app=express();app.set('view engine','jade');app.use(bodyparser.urlencoded({extended: true}))app.get('/',function(req,res,next){ //http响应文件上传页面 res.render(view+'index.jade');};//文件上传处理逻辑app.post('/upload',function(req,res,next){ var now=date.parse(new date())/1000; var form=new formidable.incomingform(), fields=[], basename=__dirname+'/uploadfile/'+now, imagename=basename+'.png', //源图片路径 newname=basename+'_small'+'.png', //新文件路径 pathname='/uploadfile/'+now+'_small'+'.png'; form.on('field',function(field,value){ fields.push([field,value]); }); form.parse(req,function(error,fields,files){ var size=''+fields.width+'x'+fields.height fs.renamesync(files.image.path,imagename); imageresize(fields.width, fields.height, imagename, newname,res); })};app.listen('监听端口号');
form.parse(request, [callback]) 该方法会转换请求中所包含的表单数据,callback会包含所有字段域和文件信息
文件上传功能同样是应用formidable 模块,当然这里还应用到其获取post数据的方法。formidable 模块提供了获取field参数的api form.on的field 事件,监听post数据传递。所有的post数据都需要应用form.parse 进行解析,解析返回fields对象和文件对象files。根据获取的width和height,调用imageresize对图片进行相应的压缩处理。
然后去实现imageresize函数:imageresize函数的主要功能是应用udp模块连接udpserver,将相应的参数数据转化为json字符通过udp协议传递到udpserver,并将udpserver响应的数据通过res.render直接返回显示到相应的页面
function imageresize(width,height,imagepath,newname,res){ var imagejson={ 'width':width, 'height':height, 'url':imagepath, 'new_name':newname }; var jsonstr=json.stringify(imagejson); var client=dgram.createsocket(udp4); var message=new buffer(jsonstr); client.send(message,0,message.length,server端监听的端口号,域名,function(){ client.on(message,function(msg,rinfo){ var retjson=json.parse(msg); if(retjson.code===0){ res.render(view+'main.jade',{'url':pathname,'err':'ok'}); }else{ res.render(view+'main.jade',{'url':'','err':'error'}); } }) })}
前端模板jade部分就先省去。。。
更多编程相关知识,请访问:编程视频!!
以上就是node+udp实现图片裁剪功能的详细内容。