国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

有趣的 JavaScript 格式轉換

fireflow / 2010人閱讀

摘要:位無符號整數,長度個字節,溢出處理為最大值。所以你拿到的英文字母編碼前后一樣的,但是漢字等字符就不同了。為了直接得到漢字的碼,使用其實還可以選擇使用處理漢字,但是英文又不能正常轉換了。

原文鏈接:https://ssshooter.com/2019-04...

之前做文件上傳和 canvas 修圖時接觸到幾個格式,這里打算整理一下他們的關系

Blob

使用 input 獲取文件時,你拿到的就是 file 對象,而 file 繼承于 blob,所以直接講比較陌生的 blob 吧。

BLOB (binary large object),二進制大對象,是一個可以存儲二進制文件的“容器”。

Blob 有什么用

使用 Blob 可以讓你在瀏覽器生成一個臨時文件,使用 URL.createObjectURL() 獲取他的鏈接,你就能像服務器文件一樣使用他。

let temp = new Blob(["hello fantasy"])
URL.createObjectURL(temp)
// 返回 "blob:https://ssshooter.com/1bf84bba-b53a-4155-8348-33a487e8ab7e"

返回的 url 前面是主機,后面是一個唯一識別碼。

在創建這個臨時文件后,只要不關閉當前頁面,這個文件就會一直存在于內存,你需要主動運行 URL.revokeObjectURL(url) 刪除引用。

從 Blob 中提取數據

在控制臺打出 blob 你根本不知道里面是啥,那么怎么讀取 blob 呢?

借助 FileReader,你可以把 Blob 讀取為 Buffer。

FileReader 對象允許 Web 應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩沖區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。
var reader = new FileReader()
reader.addEventListener("loadend", function() {
  // reader.result 包含轉化為類型數組的blob
})
reader.readAsArrayBuffer(blob)
ArrayBuffer

經過 FileReader 的讀取,你能看到計算機儲存數據的本質 —— 二進制數據。

ArrayBuffer 的編輯

ArrayBuffer 類似數組,每一格放入 1Byte(8bit)數據,也就是八位的 0 或 1,所以換成十進制一格最大是 255.

例如:

ArrayBuffer 不能直接操作,而是要通過類型數組對象(下面列出來的)或 DataView 對象來操作,它們會將緩沖區中的數據表示為特定的格式,并通過這些格式來讀寫緩沖區的內容。

Int8Array:8 位有符號整數,長度 1 個字節,溢出處理為 數值%(取模)255。

Uint8Array:8 位無符號整數,長度 1 個字節。

Uint8ClampedArray:8 位無符號整數,長度 1 個字節,溢出處理為 255(最大值)。

Int16Array:16 位有符號整數,長度 2 個字節。

Uint16Array:16 位無符號整數,長度 2 個字節。

Int32Array:32 位有符號整數,長度 4 個字節。

Uint32Array:32 位無符號整數,長度 4 個字節。

Float32Array:32 位浮點數,長度 4 個字節。

Float64Array:64 位浮點數,長度 8 個字節。

對應視圖的轉換還很神奇的,ArrayBuffer 是一個格子 8 位,也就是跟 xx8Array 是一樣的,自然不用轉換,而 16 之后的都是把每幾個格子合成一個。

// 創建 buffer
ab = new ArrayBuffer(4)
// 創建視圖
a = new Uint8Array(ab)
// 通過視圖操作 buffer
a[0] = 2
a[1] = 25
a[2] = 31
a[2] = 233

打印 ab 會輸出:

為了方便理解他們如何轉換,我把他轉為 2 進制:

// Int16Array
;["1100100000010", "11101001"]
// Int32Array
;["111010010001100100000010"]
// Uint8Array
;["10", "11001", "11101001", "0"]

可能還沒能看出來?那再在前面補 0:

// Int16Array
;["0001100100000010", "0000000011101001"]
// Int32Array
;["00000000111010010001100100000010"]
// Uint8Array
;["00000010", "00011001", "11101001", "00000000"]

這就很明顯能看出:要轉換就要在分組之后把同一組數據從右到左拼接。

不過我自覺一般不太會用到這么細致的 bit 操作(

canvas 與 buffer

另外,canvas 可以通過 ctx.createImageData() 得到 ImageData

ImageData.data 就是一個 Uint8ClampedArray,里面順序放著圖片每一個像素的 rgba 值。你可以對這個 Uint8ClampedArray 進行一系列操作,再用 canvas.toBlob 這個 buffer 變回 Blob,就完成了圖片編輯的操作。

通過這個操作,再結合一些卷積核相關知識,就能完成類似這個卷積核圖片修改器的功能。

Data Url

Data Url 是一個前綴為 data:協議,你可以借助這個協議在文檔中嵌入一些小文件(最常見就是內聯圖片了),數據格式如下:

data:[][;base64],

mediatype 填入MIME 類型,MIME 也用于服務器返回數據時指定數據類型;base64 是一種編碼方式;后面接著就是數據本體。

幾個例子:

普通文字:data:,Hello%2C%20World!

base64 處理的文字:data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D

html 文檔:data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E

執行 script 的 html 文檔:data:text/html,

base64

上面提到的 base64 不算是一種加密算法,它只是簡單地將每 3 個 8bit 字符轉換為 4 個 6Bit 字符(base64 只有 2^6 = 64 種字符,因此得名),這樣保證了傳輸中必定使用 ASCII 中可見字符,不會出奇怪的空白字符或是功能性標志 。

由于是 3 個字符變 4 個,那么很明顯了,base64 編碼后,編碼對象的體積會變成原來的 4/3 倍

特別要注意的是如果 bit 數不能被 3 整除,需要在末尾添加 1 或 2 個 byte(8 或 16bit),并且末尾的 0 不使用 A 而使用 =,這就是為什么 base64 有的編碼結果后面會有一或兩個等號。

喜聞樂見的舉例時間:

前置知識點:utf8 與 unicode 的關系

你可以使用 charCodeAt() 獲取一個字符的 unicode 編碼(0 到 65535 之間的整數),但是 unicode 只是一個碼表,并不是一個具體的編碼方式,utf8 才是。所以你拿到的英文字母編碼前后一樣的,但是漢字(等字符)就不同了。

為了直接得到漢字的 utf8 碼,使用 TextEncoder(其實還可以選擇使用 encodeURIComponent 處理漢字,但是英文又不能正常轉換了)。

下面用 JavaScript 簡單寫個 base64 轉換流程:

var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Array.from(new TextEncoder().encode("碧藍幻想"))
  .map(val => val.toString(2).padStart(8, 0)) // 轉二進制,補充到八位
  .join("")
  .replace(/([10]{6})/g, "$1,") // 每六位插個逗號用于拆分
  .split(",") // 拆分為每 6 位一組
  .map(val => parseInt(val.padEnd(6, 0), 2)) // 補充后面的 0(但是沒有補夠)
  .map(val => b64[val])
  .join("")

結果基本是對的,但是后面的 = 還是用了普通的 A 而且位數沒有加夠,所以上面轉換出來的不是標準 base64,僅供參考

base64 算法參考

blob url 與 Data Url 對比

blob url

不需要做編碼,省了運算資源

大小也不會改變

在不使用時需要手動刪除引用

關閉頁面鏈接自動廢棄

Data Url

需要編碼,且體積變大 1.3 倍

容易刪除

鏈接不變,保存了可以以后使用

參考

mdn Blob

mdn FileReader

mdn HTMLCanvasElement

阮一峰 ES6 arraybuffer

進階 FileAPI 實現標準

javascript info - blob

附錄 N 進制數的表示方法
// 10
var a = 10
// 8
var b = 0o1234567
// 或直接在前面加0,如果后面數字都小于8就自動變成8進制
var c = 01234567
// 2
var d = 0b1010101110101
// 16
var e = 0xe87a90
N 進制數轉 10 進制
parseInt(0o1234567, 8)
parseInt(0b1010101110101, 2)
parseInt(0xe87a90, 16)
10 進制數轉 N 進制
;(123456).toString(2)
;(123456).toString(8)
;(123456).toString(16)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105969.html

相關文章

  • JavaScriptSource Map (sourceURL / sourceMappingUR

    摘要:常見的源碼轉換,主要是以下三種情況壓縮,減小體積。該項是一個數組,表示可能存在多個文件合并。第一層是行對應,以分號表示,每個分號對應轉換后源碼的一行。在這個位中,左邊的第一位最高位表示是否連續。 這兩天完成了自己的個人任務,準備學習一下前輩們的經驗教訓,在項目組的文檔中發現了一個要求注意的點,如下: Js文件的開頭可以加上類似//@ sourceURL=jquery.extends.j...

    renweihub 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<