整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          小猿圈入門html5教程之利用canvas實現圖片壓縮方法

          在學習前端你的小伙伴都在迷茫遇到問題,找不到老師怎么辦?這些也是小猿圈web前端老師擔心的,以后每天小猿圈都會為大家分享一些關于學習前端中的一些小問題,今天分享的是利用canvas實現圖片壓縮方法。

          項目中做身份證識別時,需要傳送圖片的base64格式編碼,但是手機拍攝的照片都太大了,轉成base64簡直可怕,因此找了一下解決辦法。

          涉及到的知識點

          onchange事件是在上傳完文件之后觸發

          使用files屬性獲取到上傳的文件對象

          readAsDataURL用于轉換成base64編碼

          區分canvas的畫布和繪畫環境:

          畫布:對應代碼中的cvs,可以設置畫布width,height;

          繪畫環境:對應代碼中的ctx,可以設置fillStyle,fillRect等;

          使用canvas自帶的drawImage()方法將圖片畫到canvas上

          想取到壓縮后圖片的base64可以使用canvas自帶的toDataURL()方法

          完整代碼

          <!DOCTYPEhtml>

          <htmllang="en">

          <head>

          <metacharset="UTF-8">

          <metaname="viewport"content="width=device-width,initial-scale=1.0">

          <metahttp-equiv="X-UA-Compatible"content="ie=edge">

          <title>Document</title>

          </head>

          <body>

          <inputtype="file"onchange="loadImg(this)">

          <hr>

          <div>800×449,544KB</div>

          <imgsrc=""alt="">

          <hr>

          <div>400×224,157KB</div>

          <canvas></canvas>

          <script>

          //上傳圖片

          functionloadImg(me){

          letimg=document.querySelector('img');

          letcvs=document.querySelector('canvas');

          letfile=me.files[0];//獲取到文件對象

          //上傳的圖片大于500KB時才壓縮

          if(file&&(file.size/1024>500)){

          letreader=newFileReader();

          reader.readAsDataURL(file);//轉成base64編碼

          reader.onload=function(e){

          letnaturalBase64=e.target.result;//獲取base64編碼,這是原圖的

          img.src=naturalBase64;

          img.onload=function(){

          letratio=img.naturalWidth/img.naturalHeight;//獲取原圖比例,為了等比壓縮

          cvs.width=400;

          cvs.height=cvs.width/ratio;

          letctx=cvs.getContext('2d');

          ctx.drawImage(img,0,0,cvs.width,cvs.height);//畫在canvas上

          //壓縮后新圖的base64

          letzipBase64=cvs.toDataURL();

          }

          }

          }

          }

          </script>

          </body>

          </html>

          關于壓縮后的圖片大小

          這里提供一個開箱即用的方法,baseStr是一個完整的Base64編碼

          代碼:

          functioncalcBase(baseStr){

          vartag='base64,';

          baseStr=baseStr.substring(baseStr.indexOf(tag)+tag.length);

          vareqTagIndex=baseStr.indexOf('=');

          baseStr=eqTagIndex!=-1?baseStr.substring(0,eqTagIndex):baseStr;

          varstrLen=baseStr.length;

          varfileSize=strLen-(strLen/8)*2;

          console.log("文件大小:"+(fileSize/1024).toFixed(1)+'KB');

          }

          今天的知識點就分享到這里了,有需要的朋友歡迎點贊評論轉發,想了解更多web前端開發內容的朋友可以關注小猿圈的每天的動態,會不定時更新很多更好的內容奉獻給大家,希望對你的學習有所幫助。

          朱哥,昨天試了幾把圖片上傳的功能,感覺還不錯,不過有個小問題!"

          老朱:“什么問題?”

          小白:“小圖片上傳還好說,大圖片上傳的時候經常會卡頓一下。”

          老朱:“恩,很多人上傳圖片的時候都是直接上傳原圖的,很多相機照的原圖大小都在4M左右,上傳的圖片如果都是這么大,不但用戶覺得你的網站速度慢,還非常占服務器空間。”

          小白:“哦,確實是,很多人壓根不知道自己上傳的圖片到底有多大。”

          老朱:“所以我們要讓用戶進行傻瓜式操作,圖片壓縮的功能就必不可少。今天我們就用canvas來做一下圖片壓縮的處理。我們在昨天的基礎上增加canvas功能就可以了。”

          老朱:“在縮略圖下面增加一個canvas,canvas有一個toDataURL方法,可以把當前的canvas繪制的內容進行圖片壓縮并轉換為base64編碼,有了base64編碼我們就可以發送給圖片上傳的php頁面進行圖片上傳了。”

          老朱繼續說道:“知道了壓縮的方法,我們只需要解決如果把選擇的文件繪制到canvas上面就可以了。還記得我們之前繪制圖片的時候用到的Image對象么?”

          “記得,繪制圖像的時候需要實例化一個Image對象,然后設定Image對象的圖片地址src,當圖片加載完成以后把圖片繪制到canvas上。”

          老朱:“恩,流程還記得,不錯。Image對象的src屬性也可以接收圖片base64編碼,因此我們可以這樣來做。”

          “這里我把canvas的寬度設定在500像素,高度根據圖片高度進行等比例變化,你可以看一下繪制的效果。”

          你看看這張圖片的原始大小信息:

          “現在通過imgdata=canvas.toDataURL('image/jpeg',0.3);把canvas信息壓縮并轉為base64編碼存到imgdata里面,然后通過jQuery的ajax把imgdata發送給圖片上傳的php頁面就可以了。”

          “通過canvas上傳以后圖片的大小下降到9.65K,應該說是沒非常理想了。通過canvas壓縮后上傳最大的好處是圖片在客戶端進行處理,處理好以后再往服務器發送,這樣傳輸的數據大小就非常小了。”

          老朱最后說:“剛剛我們通過canvas實現了圖片壓縮上傳,真正開發的時候情況會比這個稍微復雜點,我跟你大概說一下,你記住就行了。1、動態生成canvas,這樣做的好處是canvas不會顯示在頁面上。2、判斷圖片大小,如果圖片大小比較小不用壓縮直接上傳就可以,圖片大再進行壓縮。3、有時你可能需要隱藏input file,比如上傳頭像的功能,用戶點擊頭像進行選擇圖片上傳,這時就需要通過點擊頭像的事件調用input file的點擊事件來選擇圖片。這幾個技巧你有時間了可以自己實現一下,不是特別麻煩,我們之前學過的知識足夠你解決它們了。”


          想學H5的朋友可以關注老爐,您的關注是我持續更新《小白HTML5成長之路》的動力!

          下截圖:

          點擊文件選擇框,我們不妨選一張尺寸比較大的圖片,例如下面這種2M多的釣魚收獲照:

          于是圖片歘歘歘地傳上去了:

          此時我們點擊最終上傳完畢的圖片地址,會發現原來2M多3000多像素寬的圖片被限制為400像素寬了:

          保存到本地會發現圖片尺寸已經變成只有70K了:

          以上就是圖片前端壓縮并上傳demo的完整演示。

          二、實現原理

          要想使用JS實現圖片的壓縮效果,原理其實很簡單,核心API就是使用canvas的drawImage()方法。

          Canvas本質上就是一張位圖,而drawImage()方法可以把一張大大的圖片繪制在小小的Canvas畫布上,不久等同于圖片尺寸壓縮了?

          對于本案例的壓縮,使用的5個參數的API方法:

          context.drawImage(img, dx, dy, dWidth, dHeight);復制代碼
          

          各參數具體含義可以參見“Canvas API中文文檔-drawImage”,這里不展開。

          舉例:

          一張圖片(假設圖片對象是img)的原始尺寸是4000*3000,現在需要把尺寸限制為400*300大小,很簡單,原理如下代碼示意:

          var canvas = document.createElement('canvas');
          var context = canvas.getContext('2d');
          canvas.width = 400;
          canvas.height = 300;
          // 核心JS就這個
          context.drawImage(img,0,0,400,300);復制代碼
          

          把大圖片畫在一張小畫布上,壓縮就這么實現了,是不是簡單的有點超乎想象。

          三、如果想要上傳或下載?

          如果想要上傳圖片或者下載圖片,可以使用canvas.toDataURL()或者canvas.toBlob()方法先進行轉換。

          1. canvas.toDataURL()

          語法如下:canvas.toDataURL(mimeType, qualityArgument)復制代碼
          

          可以把畫布轉換成base64格式信息圖像信息,純字符的圖片表示法。

          其中:

          mimeType表示canvas導出來的base64圖片的類型,默認是png格式,也即是默認值是'image/png',我們也可以指定為jpg格式'image/jpeg'或者webp等格式。file對象中的file.type就是文件的mimeType類型,在轉換時候正好可以直接拿來用(如果有file對象)。

          qualityArgument表示導出的圖片質量,只要導出為jpg和webp格式的時候此參數才有效果,默認值是0.92,是一個比較合理的圖片質量輸出參數,通常情況下,我們無需再設定。

          更多關于toDataURL()方法的信息可以參見“Canvas API中文文檔-toDataURL()”。

          2. canvas.toBlob()方法

          語法如下:canvas.toBlob(callback, mimeType, qualityArgument)復制代碼
          

          可以把畫布轉換成Blob文件,通常用在文件上傳中,因為是二進制的,對后端更加友好。

          和toDataURL()方法相比,toBlob()方法是異步的,因此多了個callback參數,這個callback回調方法默認的第一個參數就是轉換好的blob文件信息,本文一開始的demo案例中的文件上傳就是將canvas圖片轉換成二進制的blob文件,然后再ajax上傳的,代碼如下:

          // canvas轉為blob并上傳
          canvas.toBlob(function (blob) {
           // 圖片ajax上傳
           var xhr = new XMLHttpRequest();
           // 開始上傳
           xhr.open("POST", 'upload.php', true);
           xhr.send(blob); 
          });復制代碼
          

          更多關于toBlob()方法的信息可以參見“Canvas API中文文檔-toBlob()”。

          一旦有了可傳輸的圖像數據,上傳下載就好實現了。例如下載前端壓縮好的圖片,可以參考我上一篇在掘金發布的文章:“純JS生成并下載各種文本文件或圖片”。

          四、總結

          經過“圖片→canvas壓縮→圖片”三步曲,我們完成了圖片前端壓縮功能。

          作者:張鑫旭

          鏈接:https://juejin.im/post/5bec3c6cf265da614312a0fa

          來源:掘金

          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


          主站蜘蛛池模板: 一区二区精品视频| 无码一区二区三区中文字幕| 国产精品一区三区| 97精品一区二区视频在线观看| 精品一区二区三区免费毛片| 射精专区一区二区朝鲜| 亚洲AV网一区二区三区| 中文字幕一区二区视频| 精品国产乱子伦一区二区三区 | 久久国产三级无码一区二区| 区三区激情福利综合中文字幕在线一区| 亚洲一区电影在线观看| 久久亚洲综合色一区二区三区 | 日韩免费无码一区二区视频| 蜜桃臀无码内射一区二区三区| 大伊香蕉精品一区视频在线| 视频一区视频二区日韩专区| 无码日韩精品一区二区人妻| 亚洲欧洲专线一区| 中文字幕无线码一区二区| 69久久精品无码一区二区| 麻豆亚洲av熟女国产一区二| 久久无码人妻一区二区三区午夜| 亚洲AV日韩AV天堂一区二区三区 | 无码人妻精品一区二区三区66| 国产一区二区精品尤物| 一区二区三区免费在线观看| 亚洲人成网站18禁止一区| 亚洲视频在线一区二区| 香蕉免费看一区二区三区| 亚洲色无码一区二区三区| 久久精品岛国av一区二区无码| 无码一区二区三区在线观看| 久久久无码精品国产一区| 国产福利微拍精品一区二区| 成人精品视频一区二区三区尤物| 国产精品成人99一区无码| 国产在线观看一区二区三区 | 日本一区二区高清不卡| 无码欧精品亚洲日韩一区夜夜嗨 | 麻豆国产在线不卡一区二区|