亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

node.js(express)中使用Jcrop進行圖片剪切上傳功能

發布時間:2020-09-01 04:51:00 來源:腳本之家 閱讀:159 作者:xiashulin 欄目:web開發

需求說明

簡單來說就是要實現用戶上傳頭像,并且要保存用戶裁切后的部分作為用戶頭像。

第一步,選擇圖片:

node.js(express)中使用Jcrop進行圖片剪切上傳功能 

第二步,在彈窗頁面中展現并進行裁切:

node.js(express)中使用Jcrop進行圖片剪切上傳功能 

第三步,點擊“保存”,上傳服務器

實現過程

說來有點坎坷,相當于做了2遍,走了彎路。

第1遍是用戶一選擇圖片,就進行了上傳,然后返回一個地址,所以在彈層上展現的圖片已經是服務器上的圖片了,然后進行裁切,再保存。

第2遍找到的一個方法,是在第1遍做到裁切處理時候想到的,即彈層展現的是用戶機器上選擇的圖片,不用先上傳,但是用image/base64來展現的。這樣就與服務器少了一次交互啊,并且服務器不用存儲2遍圖片,還提高了彈層展現速度,體驗更好,所以是極好的。

說下碰到的主要技術點:

express框架不用多說,就是保存的時候post一下裁切后的base64數據,后臺寫個對應路由就好。
Jquery也不用多說,頁面展現控制與ajax提交。

HTML5/FileReader/canvas,FileReader用于將文件讀取為數據,我們使用它的onLoad事件;canvas這個用作裁切移動時,實時重繪裁切后的圖片(相當于實時預覽,當然我是隱藏了,調試的時候可以讓他display),可以隱藏,最后上傳的其實就是這個canvas的base64數據。

Jcrop plugin。這個是裁切插件,必須的了。下載與說明在這里。
其他就是base64字符串保存成圖片了,這在服務端比較簡單,直接用fs.writeFile(fileName,dataBuffer,function(err){});就好了。

具體代碼

view頁面,主要需要有一個上傳控件,還有定義彈窗div以及用于重繪裁切范圍圖片的canvas,當然頁面要引用相應的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,處理圖片加載與裁切上傳。

首先要監控上傳控件的變化,因為我們這里沒有按鈕來觸發,所以直接監控upLoadImg1的change來觸發。

$('#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("請選擇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();
  // 將彈窗中的圖片路徑設置為選擇的圖片的base64
  $('#Img1').attr('src', e.target.result);
  // 裁切組件初始化
  initJcrop();
 };
});

裁切在彈窗一顯示的時候就應該初始化:

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;
  //設置初始選中裁切范圍
  this.setSelect([0, 0, bWidth, bHeight]);
  //原始圖片縮小比例
  try {
   wdthScale = $('#Img1')["0"].width / 222;
   heightScale = $('#Img1')["0"].height / 238;
  } catch (e) {}
  jcrop_api = this;
 });
}

非常重要的一個坑是,在此之前要定義全局變量jcrop_api,widthScale和heightScale,2個scale變量用于記錄選擇的原始圖片尺寸與在彈窗上展現尺寸的縮小/放大比例的,比如選擇的是1024x768的圖片,但是彈窗上展現的范圍是222x238,這就需要將縮小的倍數記錄下來,在裁切的重繪canvas的時候要乘以這個倍數,否則裁切的范圍就是在這個222x236尺寸上裁切的,而不是原始圖片的尺寸上裁切的。而前面的jcrop_api變量用于重新選擇圖片時要將上一次的裁切初始化組件destroy掉。

Jcrop組件中重要的事件:onChange和onSelect,用于確定裁切范圍的坐標(尺寸),因此也非常重要,其實重繪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);
}

另外就是處理保存按鈕來,一個ajax來提交canvas形成的圖片的base64字符串,后臺接受保存就可以了。

 var data = document.getElementById('myCanva').toDataURL();
 $.ajax({
  url: '/xxxx',
  type: 'POST',
  dataType: 'JSON',
  cache: false,
  data: {
   'imgData': data
  },
  success: function(res) {},
  error: function(err) {}
 });

這就是上傳裁切(實時預覽)的全部過程了。

以上所述是小編給大家介紹的node.js(express)中使用Jcrop進行圖片剪切上傳功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

霞浦县| 开原市| 南昌县| 浦东新区| 阳城县| 高陵县| 汤阴县| 读书| 垦利县| 大理市| 阜新市| 文山县| 昌黎县| 宿州市| 鲁山县| 临邑县| 古丈县| 贺州市| 柘荣县| 岳西县| 杭锦旗| 伽师县| 黔西| 西乡县| 乐昌市| 上犹县| 榆社县| 丹凤县| 余江县| 安国市| 咸宁市| 务川| 兴国县| 赤水市| 乌拉特前旗| 师宗县| 大连市| 舞阳县| 广元市| 渭南市| 昌黎县|