圖片處理

圖片流

前端所說的圖片流就是讀取本地圖片,并在頁面使用文件流的方式顯示出來。

首先,我們簡單說下文件上傳的幾種方式

上傳方式

input

通過用戶點擊,創(chuàng)建<input type="file" accept="image/*"/>,并監(jiān)聽change事件獲取file對象,大體如下

click = () => {
    let input = document.createElement('input')
    input.setAttribute('type', 'file')
    input.setAttribute('accept', 'image/*')
    
    input.onchange = event => {
        let file = event.target.files[0]
    }
    
    input.click()
    
} 

Drag && drop

使用HTML5的拖放API,監(jiān)聽元素的drop事件,同樣是獲取file對象

會創(chuàng)建一個DataTransfer對象,下面我們還會遇到它,稍后再說

dragover = event => {
   event.preventDefault()
}

drop = event => {
    event.preventDefault()
    let files =  event.dataTransfer.files
}

paste

給元素綁定粘貼事件,得益于contenteditable我們可以給所有元素添加,濤聲依舊,獲取event中包含的file

paste = (e) => {
    e.preventDefault()
    let file = e.clipboardData.files[0]
}

clipboardData

paste事件提供了一個clipboardData屬性,是一個DataTransfer類型的對象,前面我們說到,拖放會產(chǎn)生一個DataTransfer對象,沒錯,粘貼也是它。

來來來,掀起了她的蓋頭來。

01.jpg

上面可以看到,clipboardData有如下屬性

  • dropEffect 默認(rèn)是node
  • effectAllowed 默認(rèn)是uninitialized
  • files 本地文件列表
  • items 剪切板中的各項數(shù)據(jù)
  • types 剪切板中的各項數(shù)據(jù)類型

我們只需要使用files即可,圖片文件在它里面

文件格式

file

通常情況下, File 對象是來自用戶在一個<input>元素上選擇文件后返回的 FileList 對象,也可以是來自由拖放操作生成的DataTransfer對象,繼承于Blob

廬山真面目,諾,就是這個樣子。

02.jpg

可以看到有如下屬性:

  • name:文件名,該屬性只讀。
  • size:文件大小,單位為字節(jié),該屬性只讀。
  • type:文件的 MIME 類型,如果分辨不出類型,則為空字符串,該屬性只讀。
  • lastModified:文件的上次修改時間,格式為時間戳。
  • lastModifiedDate:文件的上次修改時間,格式為 Date 對象實例。

我們不去深究file對象,只需要知道通過它可以訪問本地的文件。

blob

一個 Blob對象表示一個不可變的, 原始數(shù)據(jù)的類似文件對象。Blob表示的數(shù)據(jù)不一定是一個JavaScript原生格式。 File 接口基于Blob,繼承 blob功能并將其擴(kuò)展為支持用戶系統(tǒng)上的文件。

創(chuàng)建blob對象

var aBlob = new Blob( array, options );
  • array 是一個由ArrayBuffer, ArrayBufferView, Blob, DOMString 等對象構(gòu)成的 Array ,或者其他類似對象的混合體,它將會被放進(jìn) Blob.

  • options 是一個可選的Blob熟悉字典,它可能會指定如下兩種屬性

    • type,默認(rèn)值為 “”,它代表了將會被放入到blob中的數(shù)組內(nèi)容的MIME類型。

    • endings,默認(rèn)值為”transparent”,它代表包含行結(jié)束符\n的字符串如何被輸出。

var a = ["hello", "world"];
var myBlob = new Blob(a, { "type" : "text/xml" });
console.log(myBlob);
03.jpg

通過動態(tài)創(chuàng)建blob,我們可以實現(xiàn)純前端下載

const foo = {hello: "world"};
const blob = new Blob([JSON.stringify(foo)], {type: "text/plain"});
const fileName = `${new Date().valueOf()}.doc`;
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
window.URL.revokeObjectURL(link.href);

Blob URL

Blob URL是blob協(xié)議的URL,格式如下

blob:http://localhost:1234/946644c4-ca98-405e-918c-759e790d0330

Blob URL可以通過URL.createObjectURL(blob)創(chuàng)建, 在每次調(diào)用createObjectURL()方法時,都會創(chuàng)建一個新的 URL 對象,即使你已經(jīng)用相同的對象作為參數(shù)創(chuàng)建過。

在不需要這些URL對象的時候, 通過URL.revokeObjectURL(objectURL) 釋放URL對象

使用Blob URL進(jìn)行顯示本地圖片,我們只需要把創(chuàng)建的URL賦值給img的src屬性就可以了。

05.jpg

FileReader

FileReader用來讀取file或blob文件數(shù)據(jù),基于文件大小不同,讀取的過程為異步。

let render = new FileReader()
render.onload = () => {
    let src = render.result
}
render.readAsDataURL(file)

FileReader讀取文件方法

  • readAsBinaryString file 將文件讀取為二進(jìn)制編碼

  • readAsBinaryArray file 將文件讀取為二進(jìn)制數(shù)組

  • readAsText file[, encoding] 按照格式將文件讀取為文本,encode默認(rèn)為UTF-8

  • readAsDataURL file 將文件讀取為DataUrl

base64

使用FileReader進(jìn)行文件的讀取,就可以將圖片讀取成base64格式的了。

04.jpg

直接在FileReader實例的onload函數(shù)里面將result賦值給src即可

格式差異

其實主要是兩種格式base64和blob,它們之間的差異如下

  • Blob URL的長度一般比較短

  • Blob URL可以方便的使用XMLHttpRequest獲取源數(shù)據(jù), base64不是所有瀏覽器都支持

  • Blob URL 只能在當(dāng)前應(yīng)用內(nèi)部使用

格式之間轉(zhuǎn)換

canvas轉(zhuǎn)為blob對象

canvas.toBlob(function (blobObj) {
    console.log(blobObj)
})

canvas轉(zhuǎn)為base64

let imgSrc = canvas.toDataURL('image/png')

base64轉(zhuǎn)為blob

function dataURLtoBlob(dataurl) {
  let arr = dataurl.split(",");
  let mime = arr[0].match(/:(.*?);/)[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);

  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }

  return new Blob([u8arr], { type: mime });
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容