1. 程式人生 > >前端圖片壓縮上傳和顯示

前端圖片壓縮上傳和顯示

最近在寫一個修改頭像的功能,涉及到圖片的壓縮上傳和顯示,主要用到了以下幾個知識點:

  • 利用input [type=”file”]上傳圖片
  • 利用FileReader的readAsDataURL讀取圖片將其轉為base64
  • 當圖片很大的時候利用canvas進行圖片壓縮

    關於input [type=”file”]

  • type 型別為 file 的 input 元素,讓使用者可以選擇一個或多個元素以提交表單的方式上傳到伺服器上, 或者通過 Javascript 的 File API 對檔案進行操作。
  • 可以用通過監聽change事件來監聽input file中檔案的變化
  • 屬性值有以下幾個比較常用:
    • accept:表示可以選擇的檔案MIME型別,多個MIME型別用英文逗號分開,常用的MIME型別見下表。
    • multiple:是否可以選擇多個檔案,多個檔案時其value值為第一個檔案的虛擬路徑。
  • 所有type屬性為file的 input元素都有一個files屬性,用來儲存使用者所選擇的檔案,在控制檯輸入如下
FileList {0: File(210251), length: 1}
    0:File(210251)
        lastModified:1526814216420
        lastModifiedDate:Sun May 20 2018 19:03:36 GMT+0800 (中國標準時間) {}
        name:"哈哈哈.png"
        size:210251
type:"image/png" webkitRelativePath:"" __proto__:File length:1 __proto__:FileList

可以看出來files是一個類陣列物件,我們當前的檔案資訊被儲存在FileList[0]這個File物件上,這也就是我們之後能用FileReader讀取圖片的原因。

利用FileReader讀取圖片

  • FileReader 物件允許Web應用程式非同步讀取儲存在使用者計算機上的檔案(或原始資料緩衝區)的內容,使用 File 或 Blob 物件指定要讀取的檔案或資料。
  • FileReader.readAsDataURL()
    開始讀取指定的Blob中的內容。一旦完成,result屬性中將包含一個data: URL格式的字串以表示所讀取檔案的內容。
  • FileReader.result 只讀
    檔案的內容。該屬性僅在讀取操作完成後才有效,資料的格式取決於使用哪個方法來啟動讀取操作。
  • FileReader.onload
    處理load事件。該事件在讀取操作完成時觸發。

所以我們利用之前input file在onchange中的files[0]物件,將它作為引數傳給FilwReader.readrAsFataURL(),讀取成功的result就是一個base64的URL,然後將result賦給你要顯示的Img或者div的background,這樣圖片就可以顯示出來。

利用canvas壓縮圖片

  • canvas 元素不被一些老的瀏覽器所支援,但是所有的主流瀏覽器的新近版本都支援。Canvas 的預設大小為300畫素×150畫素(寬×高,畫素的單位是px)。但是,可以使用HTML的高度和寬度屬性來自定義Canvas 的尺寸。
  • canvas起初是空白的。為了展示,首先指令碼需要找到渲染上下文,然後在它的上面繪製。它元素有一個叫做 getContext() 的方法,這個方法是用來獲得渲染上下文和它的繪畫功能。getContext()只有一個引數,即上下文的格式。

  • 在獲得了源圖物件的情況下,可以使用 drawImage 方法將它渲染到 canvas 裡。

    • drawImage(image, x, y)
      其中 image 是 image 或者 canvas 物件,x 和 y 是其在目標 canvas 裡的起始座標。
    • drawImage(image, x, y, width, height) (壓縮圖片用到的就是這個)
      這個方法多了2個引數:width 和 height,這兩個引數用來控制 當向canvas畫入時應該縮放的大小
    • drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
      第一個引數和其它的是相同的,都是一個影象或者另一個 canvas 的引用。其它8個引數最好是參照右邊的圖解,前4個是定義影象源的切片位置和大小,後4個則是定義切片的目標顯示位置和大小。
  • canvas.toBlob(callback, mimeType, qualityArgument) 創造Blob物件,用以展示canvas上的圖片;這個圖片檔案可以被快取或儲存到本地,由使用者代理端自行決定。

    • callback
      回撥函式,可獲得一個單獨的Blob物件引數。
    • type 可選
      DOMString型別,指定圖片格式,預設格式為image/png。
    • encoderOptions 可選
      Number型別,值在0與1之間,當請求圖片格式為image/jpeg或者image/webp時用來指定圖片展示質量。如果這個引數的值不在指定型別與範圍之內,則使用預設值,其餘引數將被忽略。

    接著上面來,之前我們已經獲得了圖片的base64,所以我們可以新生成一個Image物件,在監聽該Image的load事件時,利用的canvas可以再獲取源圖物件的情況下,使用drawImage(image,x,y,width,height)的方法對圖片進行壓縮,然後利用canvas.toBlob將畫好的canvas轉為blob檔案。

粗暴解決input file樣式不滿意

最後,對於input file的預設樣式不滿意有一個粗暴的解決方法,在input上加一個div包住,將該div下的input的opacity設定為0,例如:
對比

#add {
        width: 150px;
        height: 150px;
        border: 3px solid black;
        background: url('./add.png') no-repeat;    //設定想要的效果
        background-position: center;
        background-size: 70% auto;
        float: left;
}
#add input {
        width: 100%;
        height: 100%;
        opacity: 0;
        /*border: none;*/
}

 <input type="file" name="myfile" style="margin-left:100px;"/>    <!--原始-->
 <div id="add">
      <input type="file" id="upd">
 </div>

程式碼註釋講解

//監聽input file的change事件
oUpd.addEventListener('change',function(e){
        var files = e.target.files;    //為了獲取儲存圖片的資訊的File物件
        var oImg = new Image();         //Image物件 用於之後canvas drawImage
        var reader = new FileReader();     //建立FileReader物件 
        reader.readAsDataURL(files[0]);     //利用readerDtaURL將圖片讀成base64

        reader.onload = function (e) {        //監聽reader讀取完成事件
            //當讀取完成時,reader.result就是要的base64
            oImg.src = this.result;
            //此時的result可以被當做src在適合的地方加上
        }
        //監聽oImg的完成事件 在完成之後繪製canvas
        oImg.onload = function() {
            var canvas = document.createElement('canvas');
            var context = canvas.getContext('2d');           //為canvas設定上下文

            //oImg的初始寬、高 
            var originW = oImg.width;               
            var originH = oImg.height;

            //設定能容許的最大寬、高  用於之後縮放比例 和 判斷是否需要壓縮
            var maxW = 400, maxH = 400;
            //設定目標寬、高
            var targW = originW, targH = originH;
            //判斷圖片是否超過限制  等比縮放 
            if(originW > maxW || originH > maxH) {
                if(originH/originW > maxH/maxW) {
                    targH = maxH;
                    targW = Math.round(maxH * (originW / originH));
                }else {
                    targW = maxW;
                    targH = Math.round(maxW * (originH / originW));
                }
            }
            //設定canvas的寬、高
            canvas.width = targW;
            canvas.height = targH;
            //清除畫布
            context.clearRect(0,0,targW,targH);
            //利用drawImage將圖片oImg按照目標寬、高繪製到畫布上
            context.drawImage(oImg,0,0,targW,targH);
            //此處可以將canvas加入到頁面中 和原圖(超過限制的圖)進行比較 發現寬、高確實縮了

            //將此時繪製好的canvas轉為blob
            canvas.toBlob(function (blob) {
                console.log(blob);
                //之後就可以對blob進行一系列操作
            },files.type || 'image/png');
            oView.appendChild(canvas);
        }
    },false);

相關推薦

前端圖片壓縮顯示

最近在寫一個修改頭像的功能,涉及到圖片的壓縮上傳和顯示,主要用到了以下幾個知識點: 利用input [type=”file”]上傳圖片 利用FileReader的readAsDataURL讀取圖片將其轉為base64 當圖片很大的時候利用canvas進行圖片

前端圖片壓縮(純js的質量壓縮,非大小壓縮)

默認 || callback doc 圖片格式 toc jpeg rtb src 此demo為大於1M對圖片進行壓縮上傳 若小於1M則原圖上傳,可以根據自己實際需求更改。 demo源碼如下: <!DOCTYPE html> <html> <h

移動前端圖片壓縮

safari 嘻嘻 如果 tee ini andro 並且 ons create   摘要:之前在做一個小遊戲平臺項目,有個“用戶中心”模塊,就涉及到了頭像上傳的功能。在做移動端圖片上傳的時候,傳的都是手機本地圖片,而本地圖片一般都相對比較大,拿現在的智能手機來說,平時拍很

移動前端圖片壓縮實踐

   此前有同事跟我聊過關於移動端用canvas壓縮圖片後再上傳的功能,最近有了點空閒時間,所以就實踐了一下。demo效果連結在文章底部貼出。   在做移動端圖片上傳的時候,使用者傳的都是手機本地圖片,而本地圖片一般都相對比較大,拿iphone6來說,平時拍很多圖片都是一兩M的,如果直接這樣上傳,那圖片就太

django實現圖片顯示

代碼 ngs 文件路徑 ont 添加 pac pre bubuko contex 首先安裝pillow模塊 在models.py下設置 class Notices(models.Model): NoticeCategory=models.CharField(max_

使用springboot 圖片顯示

一、application.properties配置檔案 ###檔案上傳 springboot版本2.0.4 #是否啟用檔案上傳功能 spring.servlet.multipart.enabled=true #指定檔案寫入磁碟後的閾值,預設為0 spring.

JS+HTML5實現前端圖片壓縮到騰訊的COS

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <meta name="viewport" content="w

圖片 壓縮 mongodb下載

// 獲得SpringBoot提供的mongodb的GridFS物件 @Autowired private GridFsTemplate gridFsTemplate; public ServiceResult<FileInfoAO> compressUplo

完美解決ueditorneditor圖片(視訊)成功顯示異常

(一)前言: 二次開發編輯器neditor(基於百度編輯器ueditor):介面相對於ueditor會更美觀. (二) 問題描述: 最近在公司專案中遇到一個比較奇葩的問題。neiditor編輯器上傳圖片用時,插入圖片初始為loading圖,載入成功後才顯示上傳的圖片。插入圖

前端js壓縮圖片 多圖、單圖 ajax

<script> /* 三個引數 file:一個是檔案(型別是圖片格式), w:一個是檔案壓縮的後寬度,寬度越小,位元組越小 objDiv:一個是容器或者回調函式 phot

MVC WebApi 圖片顯示

1 MVC中顯示 記憶體流 中的圖片。(不是圖片檔案) 建立一個Index用來顯示 Action: public ActionResult Index() {

django 實現圖片顯示操作

版本: django 2.0.1 python 3.6.2 準備工作: pip install pillow 安裝python圖片處理庫 pillow pip

Slog71_選取、顯示本地圖片GET !(微信小程式之雲開發-全棧時代3)

ArthurSlog SLog-71 Year·1 Guangzhou·China Sep 12th 2018 道常無為而無不為 開發環境MacOS(High Sierra 10.13.5) 需要的資訊和資訊源: 前言 ”雲開發

移動端圖片壓縮解決方案

長度 繪制圖片 slice ase 但是 choose 100萬 lis 計算 最近做移動端圖片上傳,發現圖片尤其是iPhone拍照的圖片都有2M左右,但是實際上項目中用不到這麽大,於是想到要用js在前臺進行壓縮。 解決方案如下:  【一】獲取圖片數據   先是獲取圖片數據

vue裏圖片壓縮組件

UNC cep accept posit click toa dcl v-on ati //單圖上傳 <template> <div> <div class="uploader" v-if=‘!dwimg‘&g

圖片裁剪

ada click delet relative tis hang flow 頁面 url 1.html,我添加了bootstrap模態框 <li > <span >封面美照*</span><!--<img src="im

summernote富文字編輯器實現圖片新增刪除圖片

summernote的基本使用 HTML程式碼 //div添加個id就可以 <div id="summernote" ></div> 然後JS操作 //例項化呼叫 var $summernote = $('#summernote').summernote(

TP框架圖片壓縮/

<-- 在前端的程式碼 --><form action="{:url('index/user/personal')}" method="post" enctype="multipart/form-data"> <input type="file" name="image"

spring boot 圖片顯示

首先描述一下問題,spring boot 使用的是內嵌的tomcat, 所以不清楚檔案上傳到哪裡去了, 而且spring boot 把靜態的檔案全部在啟動的時候都會載入到classpath的目錄下的,所以上傳的檔案不知相對於應用目錄在哪,也不知怎麼寫訪問路徑合適,對於新手

JS—圖片壓縮(單張)

eight ascii value size set tsa ade ready chan *vue+webpack環境,這裏的that指到vue實例 &lt;input type="file" name="file" ac