本文摘自PHP中文网,作者青灯夜游,侵删。
本篇文章给大家介绍一下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的代码框架,代码如下:
1 2 3 4 | const dgram= require ( 'dgram' );
var address=server.address();
console.log( "server listening " +address.address+ ":" +address.port);})server.bind( "监听端口号" );
|
会发现,UDP其实似乎和socket.io差不多?都是采用的监听消息流机制。而http没有这样做,所以几乎不用http去做这些高交互的事情 ―― 这固然和他们的内部实现有关。
监听完了,该干正事了:我们需要一个函数去处理图片。这个函数的触发时间要在事件流之后:
需要注意的是,在使用该工具时,必须安装imagemagick-cli系统工具软件:sudo apt-get install imagemagick --fix-missing
(否则会在运行期间抛出异常)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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回调函数中调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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}}
}
var retStr=JSON.stringify(retJson);
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端 ―― 前台服务器
1 | npm install express jade formidable body-parser
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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){
res.render(VIEW+ 'index.jade' );};
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( '监听端口号' );
|
1 | 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直接返回显示到相应的页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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实现图片裁剪功能的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
node.js中stream-可读流的使用
deno中如何使用 node 模块?
node+UDP实现图片裁剪功能
node使用iconv-lite对“gbk”格式进行转码
浅谈node中文乱码的解决方法
通过node+redi实现api速率限制
vue.js就是node吗
总结nodejs开发中常用的一些模块
一文快速了解nodejs中crypto模块的用法
node.js创建简单聊天室的方法介绍
更多相关阅读请进入《UDP》频道 >>
人民邮电出版社
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者
转载请注明出处:木庄网络博客 » Node+UDP实现图片裁剪功能