自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端文件數(shù)據(jù)格式那些事兒

開發(fā) 前端
在 Web 開發(fā)中,當(dāng)我們處理文件時(創(chuàng)建,上傳,下載),經(jīng)常會遇到二進(jìn)制數(shù)據(jù)。另一個典型的應(yīng)用場景是圖像處理。

 前言

[[434624]]

在 Web 開發(fā)中,當(dāng)我們處理文件時(創(chuàng)建,上傳,下載),經(jīng)常會遇到二進(jìn)制數(shù)據(jù)。另一個典型的應(yīng)用場景是圖像處理。

在 JavaScript 中有很多種二進(jìn)制數(shù)據(jù)格式,比如ArrayBuffer,Uint8Array,DataView,Blob,F(xiàn)ile 等等,不過 JavaScript 中的二進(jìn)制數(shù)據(jù)是以非標(biāo)準(zhǔn)方式實現(xiàn)的。

下面我們來了解下這些數(shù)據(jù)格式及相互轉(zhuǎn)換。

本文涉及到File,Blob,TypedArray,data url(Base64),blob url等等。

File

首先,我們還是拿前文的例子來看,顯示用戶選擇的圖片。

 

我們創(chuàng)建一個頁面。提供選擇圖片功能。

  1. <!DOCTYPE html> 
  2. <html> 
  3.     <head> 
  4.         <title>test</title> 
  5.     </head> 
  6.  
  7.     <body> 
  8.         <input type="file" id="fileInput" name="選擇圖片"/> 
  9.         <div class="wrap-image"
  10.             <canvas id="canvas"></canvas> 
  11.         </div> 
  12.         <script type="text/javascript"
  13.  
  14.         </script> 
  15.     </body> 
  16. </html> 

選擇圖片后,需要將圖片顯示到canvas中,我們在上面的script標(biāo)簽中加入下面的代碼:

 

  1. const fileInput = document.getElementById('fileInput'
  2. const canvas = document.getElementById('canvas'
  3. fileInput.addEventListener('change', (e) => { 
  4.     let img = new Image 
  5.     const file = e.target.files[0] 
  6.     img.src = URL.createObjectURL(file) 
  7.     img.onload = () => { 
  8.         canvas.width = img.width 
  9.         canvas.height = img.height 
  10.         const context = canvas.getContext('2d'
  11.         context.drawImage(img, 0, 0) 
  12.     } 
  13. }, false

 

選擇一張圖片后,change事件中獲取到選擇的文件e.target.files[0]:

 

前端文件數(shù)據(jù)格式那些事兒

 

File 對象是特殊類型的 Blob,可以用在任意的 Blob 類型的 context 中。

比如 FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能處理 Blob 和 File。

File 接口也繼承了 Blob 接口的屬性。上圖的Prototype展開可以看到繼承自Blob:

 

前端文件數(shù)據(jù)格式那些事兒

 

上面是最常見的file獲取方式————從<input type="file">中獲取。

 

  1. new File(fileParts, fileName, [options]) 
  • fileParts —— Blob/BufferSource/String 類型值的數(shù)組
  • fileName —— 文件名字符串
  • options —— 可選對象

FileReader

FileReader 的用途是從 Blob(因此也從 File)對象中讀取數(shù)據(jù)。

它使用事件來傳遞數(shù)據(jù),因為從磁盤讀取數(shù)據(jù)可能比較費時間。

可以讀取為3種格式:

 

前端文件數(shù)據(jù)格式那些事兒

 

比如將 Blob 讀取為 base64:

 

  1. const reader = new FileReader() 
  2. reader.readAsDataURL(file) // 將 Blob 讀取為 base64 

 

使用時選擇哪一種,要看如何使用數(shù)據(jù)。

讀取過程中有下列事件:

1、loadstart: 開始加載

2、progress: 在讀取過程中出現(xiàn)

3、load: 讀取完成,沒有 error

4、abort: 調(diào)用了 abort()取消操作

5、error: 出現(xiàn) error

6、loadend: 讀取完成,無論成功還是失敗

使用最廣泛的是load和error,比如下面的例子:

  1. <input type="file" onchange="readFile(this)"
  2.  
  3. <script> 
  4. const readFile = (input) => { 
  5.   const file = input.files[0] 
  6.   const reader = new FileReader() 
  7.   reader.readAsText(file) 
  8.   reader.onload = () => { 
  9.     console.log(reader.result) // 結(jié)果 
  10.   } 
  11.  
  12.   reader.onerror = () => { 
  13.     console.log(reader.error) // error 
  14.   } 
  15. </script> 

不過大多數(shù)情況下,我們不需要讀取Blob,通過網(wǎng)絡(luò)發(fā)送一個File很容易,像 XMLHttpRequest 或 fetch 等 API 本身就接受 File 對象?;蛘哂肬RL.createObjectURL(file) 創(chuàng)建一個短的 url,并將其賦給 。這樣,文件便可以下載文件或者將其呈現(xiàn)為圖像,作為 canvas 等的一部分。

 

Blob

用URL.createObjectURL創(chuàng)建了一個url:

 

  1. img.src = URL.createObjectURL(file) 

這里,URL.createObjectURL 取一個 Blob,并為其創(chuàng)建一個唯一的 URL,形式為 blob:/

本例中創(chuàng)建的url如下:

 

  1. blob:null/a05be8a9-78b4-4470-bdfe-5fca427781c2 

瀏覽器內(nèi)部為每個通過 URL.createObjectURL 生成的URL存儲了一個 URL → Blob 映射??梢酝ㄟ^URL訪問 Blob。

但 Blob 本身只保存在內(nèi)存中的。瀏覽器無法釋放它。

關(guān)閉頁面時會自動釋放內(nèi)存中的Blob,也可以手動釋放,通過URL.revokeObjectURL(url) 從內(nèi)部映射中移除引用,Blob 被刪除,并釋放內(nèi)存。

映射被刪除后該 URL 也就不再起作用了,也就無法通過URL再訪問Blob。

現(xiàn)在,我們了解了Blob作為URL的應(yīng)用,那Blob到底是什么呢?

Blob 由一個可選的字符串 type(通常是 MIME 類型)和 blobParts 組成,blobParts是 一系列其他 Blob 對象,字符串和 BufferSource。

 

前端文件數(shù)據(jù)格式那些事兒

 

我們可以通過構(gòu)造函數(shù)創(chuàng)建一個Blob:

 

  1. new Blob(blobParts, options) 
  • blobParts是 Blob/BufferSource/String 類型的值的數(shù)組
  • options 可選對象:

type: Blob 類型,通常是 MIME 類型,例如 image/png

endings:是否轉(zhuǎn)換換行符,使 Blob 對應(yīng)于當(dāng)前操作系統(tǒng)的換行符(\r\n 或 \n)。默認(rèn)為 “transparent”(啥也不做),不過也可以是 “native”(轉(zhuǎn)換)

比如從字符串創(chuàng)建 Blob:

 

  1. // 注意:第一個參數(shù)必須是一個數(shù)組 [...] 
  2. const blob = new Blob(['<html>…</html>'], {type: 'text/html'}) 

 

圖片 to Blob

圖像操作是通過canvas來實現(xiàn)的:

1、使用 canvas.drawImage 在 canvas 上繪制圖像(繪制后可以做一些圖像處理,比如旋轉(zhuǎn)、裁剪等等);

2、調(diào)用 canvas 的 toBlob(callback, format, quality)方法 創(chuàng)建一個 Blob。

比如,在上面的context.drawImage(img, 0, 0);后,我們把canvas轉(zhuǎn)成Blob:

 

  1. canvas.toBlob((blob) => { 
  2.   console.log('blob', blob) 
  3. }, 'image/png'

 

 

前端文件數(shù)據(jù)格式那些事兒

 

或者,更喜歡同步的寫法:

 

  1. img.onload = async () => { 
  2.   ... 
  3.   context.drawImage(img, 0, 0) 
  4.   const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')) 
  5.   console.log('blob', blob) 

 

Blob to Base64

URL.createObjectURL 的一個替代方法是,將 Blob 轉(zhuǎn)換為 base64。

base64編碼將二進(jìn)制數(shù)據(jù)表示為一個由 0 到 64 的 ASCII 碼組成的字符串,非常安全且可讀。

我們可以在 data-url 中使用base64編碼,data-url就像下面這樣:

  1. data:[<mediatype>][;base64],<data> 

我們可以像常規(guī)url一樣使用data-url 。

比如一張支持alpha透明度的webp的圖片:

  1. <img src="data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA=="

我們可以用 FileReader 將 Blob 轉(zhuǎn)換為 base64:

 

  1. // img.src = URL.createObjectURL(file) 
  2. const reader = new FileReader() 
  3. reader.readAsDataURL(file) // 將 Blob 轉(zhuǎn)換為 base64 并調(diào)用 onload 
  4.  
  5. reader.onload = () => { 
  6.   img.src = reader.result 

 

現(xiàn)在我們可以從Blob創(chuàng)建2種url,一種是blob url,一種是data url,下面我們對比下這2種方式:

 

前端文件數(shù)據(jù)格式那些事兒

 

所以要使用哪種url,需要具體情況再分析。

ArrayBuffer

基本的二進(jìn)制對象 ArrayBuffer是對固定長度的連續(xù)內(nèi)存空間的引用,是一個內(nèi)存區(qū)域,一個原始的二進(jìn)制數(shù)據(jù)。

我們可以這樣創(chuàng)建一個長度為 16 的 buffer:

 

  1. let buffer = new ArrayBuffer(16); // 創(chuàng)建一個長度為 16 的 buffer 
  • 注意:ArrayBuffer 和 Array 沒有任何關(guān)系

我們可以通過 FileReader 的 readAsArrayBuffer 讀取 Blob 的二進(jìn)制數(shù)據(jù):

 

  1. const reader = new FileReader() 
  2. reader.readAsArrayBuffer(file) 
  3. reader.onload = () => { 
  4.     const buffer = reader.result 

 

 

前端文件數(shù)據(jù)格式那些事兒

 

或者用Blob的arrayBuffer方法:

 

  1. const buffer = await file.arrayBuffer() 

上面我們看到了Int8Array、Uint8Array、Int16Array,它們的通用術(shù)語是TypedArray,此外,還有其他的TypedArray。

 

前端文件數(shù)據(jù)格式那些事兒

 

總結(jié)

現(xiàn)在回顧一下:

1、<input type="file">是最常見的File獲取方式;

2、File對象是特殊類型的 Blob;

3、Blob可以生成blob url;

4、FileReader可以讀取Blob為3種格式,二進(jìn)制格式的 ArrayBuffer,給定編碼的字符串,base64編碼的 data url;

5、blob url和data url都可以作為url使用;

6、Blob對象的arrayBuffer方法可以讀取Blob的ArrayBuffer;

7、canvas.toBlob(callback, format, quality)可以把canvas讀取為Blob;

下圖可以很直觀的看到它們之間的相關(guān)轉(zhuǎn)換關(guān)系:

 

前端文件數(shù)據(jù)格式那些事兒

 

 

 

 

責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2022-05-23 08:34:08

微前端微服務(wù)開發(fā)

2021-04-29 10:30:58

MySQL數(shù)據(jù)遷移

2018-02-02 13:58:59

數(shù)據(jù)存儲

2018-10-22 09:22:53

2016-08-31 10:55:30

螞蟻金服前端

2011-02-25 14:35:00

2018-09-26 06:50:19

2021-06-02 08:33:31

TPCTPC-H系統(tǒng)

2022-02-08 17:39:04

MySQL服務(wù)器存儲

2013-12-26 14:23:03

定位系統(tǒng)GPS監(jiān)測

2021-06-09 13:28:40

密碼安全身份認(rèn)證數(shù)據(jù)安全

2022-06-20 05:40:25

數(shù)據(jù)庫MySQL查詢

2019-12-25 15:20:48

前端腳手架命令

2024-02-06 08:33:54

文件系統(tǒng)SSD

2022-04-08 09:47:55

性能優(yōu)化開發(fā)

2022-05-13 14:36:12

網(wǎng)絡(luò)犯罪網(wǎng)絡(luò)攻擊密碼

2022-10-08 00:02:00

CSS工具系統(tǒng)

2017-05-18 16:30:29

Linux內(nèi)存管理

2010-09-14 11:36:24

上網(wǎng)行為管理網(wǎng)絡(luò)安全網(wǎng)康科技

2012-03-12 13:55:22

交互設(shè)計
點贊
收藏

51CTO技術(shù)棧公眾號