node.js(express)中使用Jcrop進(jìn)行圖片剪切上傳功能
需求說明
簡(jiǎn)單來說就是要實(shí)現(xiàn)用戶上傳頭像,并且要保存用戶裁切后的部分作為用戶頭像。
第一步,選擇圖片:
第二步,在彈窗頁面中展現(xiàn)并進(jìn)行裁切:
第三步,點(diǎn)擊“保存”,上傳服務(wù)器。
實(shí)現(xiàn)過程
說來有點(diǎn)坎坷,相當(dāng)于做了2遍,走了彎路。
第1遍是用戶一選擇圖片,就進(jìn)行了上傳,然后返回一個(gè)地址,所以在彈層上展現(xiàn)的圖片已經(jīng)是服務(wù)器上的圖片了,然后進(jìn)行裁切,再保存。
第2遍找到的一個(gè)方法,是在第1遍做到裁切處理時(shí)候想到的,即彈層展現(xiàn)的是用戶機(jī)器上選擇的圖片,不用先上傳,但是用image/base64來展現(xiàn)的。這樣就與服務(wù)器少了一次交互啊,并且服務(wù)器不用存儲(chǔ)2遍圖片,還提高了彈層展現(xiàn)速度,體驗(yàn)更好,所以是極好的。
說下碰到的主要技術(shù)點(diǎn):
express框架不用多說,就是保存的時(shí)候post一下裁切后的base64數(shù)據(jù),后臺(tái)寫個(gè)對(duì)應(yīng)路由就好。
Jquery也不用多說,頁面展現(xiàn)控制與ajax提交。
HTML5/FileReader/canvas,F(xiàn)ileReader用于將文件讀取為數(shù)據(jù),我們使用它的onLoad事件;canvas這個(gè)用作裁切移動(dòng)時(shí),實(shí)時(shí)重繪裁切后的圖片(相當(dāng)于實(shí)時(shí)預(yù)覽,當(dāng)然我是隱藏了,調(diào)試的時(shí)候可以讓他display),可以隱藏,最后上傳的其實(shí)就是這個(gè)canvas的base64數(shù)據(jù)。
Jcrop plugin。這個(gè)是裁切插件,必須的了。下載與說明在這里。
其他就是base64字符串保存成圖片了,這在服務(wù)端比較簡(jiǎn)單,直接用fs.writeFile(fileName,dataBuffer,function(err){});就好了。
具體代碼
view頁面,主要需要有一個(gè)上傳控件,還有定義彈窗div以及用于重繪裁切范圍圖片的canvas,當(dāng)然頁面要引用相應(yīng)的js插件和css等,主要:
<link rel="stylesheet" href="/css/jquery.Jcrop.css" rel="external nofollow" > <script src="/js/jquery.js"></script> <script src="/js/jquery.Jcrop.js"></script> <!--上傳控件--> <input type="file" name="upLoadImg1" id="upLoadImg1"> <!--彈窗與裁切圖--> <div class="cover"> <img id="Img1" alt=""> <button id="btnSave">保存</button> </div> <!--裁切范圍重繪canvas--> <canvas id="myCanva" width="200" height="200">
js/jQuery,處理圖片加載與裁切上傳。
首先要監(jiān)控上傳控件的變化,因?yàn)槲覀冞@里沒有按鈕來觸發(fā),所以直接監(jiān)控upLoadImg1的change來觸發(fā)。
$('#upLoadImg1').on('change', function() { if (document.getElementById("upLoadImg1").files.length === 0) { return; } var oFile = document.getElementById("upLoadImg1").files[0]; if (!oFile) { return; } var fileName = oFile.name; var fileSize = oFile.size; var fileType = fileName.substring(fileName.lastIndexOf('.'), fileName.length).toLowerCase(); if (fileType != '.jpg' && fileType != '.jpeg' && fileType != '.gif' && fileType != '.png' && fileType != '.bmp') { alert("請(qǐng)選擇jpg,png,gif,bmp格式的圖片"); return; } if (fileSize > 2 * 1024 * 1024) { alert('最大支持2MB的圖片'); return; } var fileReader = new FileReader(); fileReader.readAsDataURL(oFile); // 成功讀取 fileReader.onload = function(e) { // 顯示彈窗 $('.cover').show(); // 將彈窗中的圖片路徑設(shè)置為選擇的圖片的base64 $('#Img1').attr('src', e.target.result); // 裁切組件初始化 initJcrop(); }; });
裁切在彈窗一顯示的時(shí)候就應(yīng)該初始化:
function initJcrop() { $('#Img1').Jcrop({ onChange: updateCoords, onSelect: updateCoords, aspectRatio: 1, boxWidth: 300, boxHeight: 300 }, function() { //彈窗中顯示的圖片尺寸 var bb = this.getBounds(); var bWidth = Number(bb[0]) / 2; var bHeight = Number(bb[1]) / 2; //設(shè)置初始選中裁切范圍 this.setSelect([0, 0, bWidth, bHeight]); //原始圖片縮小比例 try { wdthScale = $('#Img1')["0"].width / 222; heightScale = $('#Img1')["0"].height / 238; } catch (e) {} jcrop_api = this; }); }
非常重要的一個(gè)坑是,在此之前要定義全局變量jcrop_api,widthScale和heightScale,2個(gè)scale變量用于記錄選擇的原始圖片尺寸與在彈窗上展現(xiàn)尺寸的縮小/放大比例的,比如選擇的是1024x768的圖片,但是彈窗上展現(xiàn)的范圍是222x238,這就需要將縮小的倍數(shù)記錄下來,在裁切的重繪canvas的時(shí)候要乘以這個(gè)倍數(shù),否則裁切的范圍就是在這個(gè)222x236尺寸上裁切的,而不是原始圖片的尺寸上裁切的。而前面的jcrop_api變量用于重新選擇圖片時(shí)要將上一次的裁切初始化組件destroy掉。
Jcrop組件中重要的事件:onChange和onSelect,用于確定裁切范圍的坐標(biāo)(尺寸),因此也非常重要,其實(shí)重繪canvas就是在這里面完成的。
function updateCoords(c) { var img = document.getElementById('Img1'); var ctx = document.getElementById('myCanva').getContext('2d'); try { wdthScale = wdthScale === 1 ? $('#Img1')["0"].width / 222 : wdthScale; heightScale = heightScale === 1 ? $('#Img1')["0"].height / 238 : heightScale; } catch (e) { } //繪制canvas畫布 ctx.drawImage(img, c.x, c.y, c.w * wdthScale, c.h * heightScale, 0, 0, 200, 200); }
另外就是處理保存按鈕來,一個(gè)ajax來提交canvas形成的圖片的base64字符串,后臺(tái)接受保存就可以了。
var data = document.getElementById('myCanva').toDataURL(); $.ajax({ url: '/xxxx', type: 'POST', dataType: 'JSON', cache: false, data: { 'imgData': data }, success: function(res) {}, error: function(err) {} });
這就是上傳裁切(實(shí)時(shí)預(yù)覽)的全部過程了。
以上所述是小編給大家介紹的node.js(express)中使用Jcrop進(jìn)行圖片剪切上傳功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Node.js的Express框架使用上手指南
- 從零開始學(xué)習(xí)Node.js系列教程之基于connect和express框架的多頁面實(shí)現(xiàn)數(shù)學(xué)運(yùn)算示例
- node.js使用express框架進(jìn)行文件上傳詳解
- node.js express框架簡(jiǎn)介與實(shí)現(xiàn)
- Node.js + express實(shí)現(xiàn)上傳大文件的方法分析【圖片、文本文件】
- 淺析Node.js實(shí)現(xiàn)HTTP文件下載
- Node.js 使用request模塊下載文件的實(shí)例
- Node.JS段點(diǎn)續(xù)傳:Nginx配置文件分段下載功能的實(shí)現(xiàn)方法
- 基于nodejs+express4.X實(shí)現(xiàn)文件下載的實(shí)例代碼
- nodejs+express實(shí)現(xiàn)文件上傳下載管理網(wǎng)站
- 使用nodejs+express實(shí)現(xiàn)簡(jiǎn)單的文件上傳功能
- node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解
相關(guān)文章
Node.js連接數(shù)據(jù)庫實(shí)現(xiàn)過程詳解
這篇文章主要為大家介紹了Node.js連接數(shù)據(jù)庫實(shí)現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12ajax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)
下面小編就為大家?guī)硪黄猘jax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08獨(dú)立部署小程序基于nodejs的服務(wù)器過程詳解
這篇文章主要介紹了獨(dú)立部署小程序基于nodejs的服務(wù)器過程詳解,完全自定義的部署小程序服務(wù)器, 不依托于騰訊云服務(wù)器體系. 以阿里云服務(wù)器為基礎(chǔ)建立.服務(wù)器語言選用nodejs.,需要的朋友可以參考下2019-06-06nodejs+axios爬取html出現(xiàn)中文亂碼并解決示例
這篇文章主要為大家介紹了nodejs+axios爬取html出現(xiàn)中文亂碼示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06nodejs+websocket實(shí)時(shí)聊天系統(tǒng)改進(jìn)版
這篇文章主要介紹了nodejs+websocket實(shí)時(shí)聊天系統(tǒng)的改進(jìn)版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05一文學(xué)會(huì)搭建HTTP服務(wù)器調(diào)用DLL庫
這篇文章主要為大家介紹了一文學(xué)會(huì)搭建HTTP服務(wù)器調(diào)用DLL庫,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06nodejs發(fā)布靜態(tài)https服務(wù)器步驟指南
這篇文章主要為大家介紹了nodejs發(fā)布靜態(tài)https服務(wù)器的步驟指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02