您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Node+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服務器。
根據上面的分析,本應用需要實現的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服務器端是如何與其交互的。
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實現圖片裁剪功能的方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。