<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在小程式開發中,需要將介面請求獲得的arrayBuffer資料,轉換為base64格式資料,進行圖片的顯示。
微信小程式提供了wx.arrayBufferToBase64方法,但很不幸,這個方法在基礎庫版本 2.4.0 起已廢棄,已不推薦使用。
雖然目前即使小程式基礎庫版本為2.22.0,也能正常使用。但是不確定未來哪天,在更新的基礎庫中,該方法被刪除。這樣就會帶來專案上的隱患。
所以需要自己去實現arrayBuffer轉為base64這一過程。
好了,條條大路都被阻斷了。那就該自己鋪路搭橋了。
問題的起始條件有arrayBuffer資料,期望結果是最終形成base64格式資料。那開始進行求解。
首先我們得來說說arrayBuffer這回事。
在JavaScript中,有一個很常用的參照資料型別Array,你可以在裡面放字串、數位、物件、布林值等等等等。它存放在堆中,可以自由增減。
ArrayBuffer 物件用來表示通用的、固定長度的原始二進位制資料緩衝區。它是一個位元組陣列,通常在其他語言中稱為“byte array”。它的誕生就是為了解決一個問題:操作二進位制資料。
只由0和1組成的二進位制資料往往是非常巨大的,上千個位元組可以說司空見慣,傳統的Array這時候處理起二進位制資料起來就顯得非常低效,所以ArrayBuffer出現了,它作為一塊專用的記憶體區域存放在棧中,取資料非常快。
我們現在通過new ArrayBuffer(10)初始化一個buffer範例,看看會得到什麼。
let buffer = new ArrayBuffer(10); console.log(buffer); // 在控制檯上顯示如下 ArrayBuffer(10) byteLength: 10 [[Prototype]]: ArrayBuffer [[Int8Array]]: Int8Array(10) [[Uint8Array]]: Uint8Array(10) [[Int16Array]]: Int16Array(5) [[ArrayBufferByteLength]]: 10 [[ArrayBufferData]]: 1367
可以看到在ArrayBuffer中,主要存放了幾個“檢視”,Int8Array表示8位元有符號整數陣列,Int16Array表示16位元有符號整數陣列,Uint8Array則表示8位元無符號整數陣列。
當然,如果比如說我們想取出Int8Array這個陣列來,是不能直接通過buffer.Int8Array來取的。這是因為ArrayBuffer不能直接通過下標去讀寫,我們需要把它轉成一個型別化陣列(TypedArray)。
你不能直接操作 ArrayBuffer 的內容,而是要通過型別陣列物件或 DataView 物件來操作,它們會將緩衝區中的資料表示為特定的格式,並通過這些格式來讀寫緩衝區的內容。
const myTypedArray = new Uint8Array(buffer)
轉化完之後,我們我們不僅可以通過下標去對型別化陣列進行索引,也可以獲取其length,當然TypedArray仍與普通的Array存在細微的區別,那就是假設我們用超出邊界的索引語法去獲取陣列元素時,TypedArray並不會去原型鏈中進行查詢。
現在我們已經拿到了這個型別化陣列,是時候把它轉成普通字串了。看看String.fromCharCode這個函數,它接受的引數為一堆程式碼單元序列,輸出一個普通字串。而我們剛剛得到的型別化陣列,裡面存放的正是程式碼單元。
const str = String.fromCharCode(...myTypedArray)
這裡我們用拓展運運算元...把型別陣列的程式碼單元解出來,一次性轉完,得到一個普通的字串。
最後,我們需要藉助一個window物件的方法,也就是btoa方法,它的作用是:把一個普通字串編碼成base-64格式的字串。
上面看似很好,但是在最後一步,btoa,在小程式中是沒有該方法的去使用的。需要自己去實現btoa這個方法。
因為該函數,在瀏覽器中已經實現,所以更多使用在小程式及node環境中。所以總體以module.exports進行方法的輸出,以require形式進行引入。
輸出方法
module.exports = { btoa: ..., atob: ... }
引入檔案
const { btoa } = require('./base64')
base64.js
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", a256 = '', r64 = [256], r256 = [256], i = 0; var UTF8 = { /** * Encode multi-byte Unicode string into utf-8 multiple single-byte characters * (BMP / basic multilingual plane only) * * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars * * @param {String} strUni Unicode string to be encoded as UTF-8 * @returns {String} encoded string */ encode: function (strUni) { // use regular expressions & String.replace callback function for better efficiency // than procedural approaches var strUtf = strUni.replace(/[u0080-u07ff]/g, // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz function (c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f); }) .replace(/[u0800-uffff]/g, // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz function (c) { var cc = c.charCodeAt(0); return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3F, 0x80 | cc & 0x3f); }); return strUtf; }, /** * Decode utf-8 encoded string back into multi-byte Unicode characters * * @param {String} strUtf UTF-8 string to be decoded back to Unicode * @returns {String} decoded string */ decode: function (strUtf) { // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char! var strUni = strUtf.replace(/[u00e0-u00ef][u0080-u00bf][u0080-u00bf]/g, // 3-byte chars function (c) { // (note parentheses for precence) var cc = ((c.charCodeAt(0) & 0x0f) << 12) | ((c.charCodeAt(1) & 0x3f) << 6) | (c.charCodeAt(2) & 0x3f); return String.fromCharCode(cc); }) .replace(/[u00c0-u00df][u0080-u00bf]/g, // 2-byte chars function (c) { // (note parentheses for precence) var cc = (c.charCodeAt(0) & 0x1f) << 6 | c.charCodeAt(1) & 0x3f; return String.fromCharCode(cc); }); return strUni; } }; while (i < 256) { var c = String.fromCharCode(i); a256 += c; r256[i] = i; r64[i] = b64.indexOf(c); ++i; } function code(s, discard, alpha, beta, w1, w2) { s = String(s); var buffer = 0, i = 0, length = s.length, result = '', bitsInBuffer = 0; while (i < length) { var c = s.charCodeAt(i); c = c < 256 ? alpha[c] : -1; buffer = (buffer << w1) + c; bitsInBuffer += w1; while (bitsInBuffer >= w2) { bitsInBuffer -= w2; var tmp = buffer >> bitsInBuffer; result += beta.charAt(tmp); buffer ^= tmp << bitsInBuffer; } ++i; } if (!discard && bitsInBuffer > 0) result += beta.charAt(buffer << (w2 - bitsInBuffer)); return result; } var Plugin = function (dir, input, encode) { return input ? Plugin[dir](input, encode) : dir ? null : this; }; Plugin.btoa = Plugin.encode = function (plain, utf8encode) { plain = Plugin.raw === false || Plugin.utf8encode || utf8encode ? UTF8.encode(plain) : plain; plain = code(plain, false, r256, b64, 8, 6); return plain + '===='.slice((plain.length % 4) || 4); }; Plugin.atob = Plugin.decode = function (coded, utf8decode) { coded = coded.replace(/[^A-Za-z0-9+/=]/g, ""); coded = String(coded).split('='); var i = coded.length; do { --i; coded[i] = code(coded[i], true, r64, a256, 6, 8); } while (i > 0); coded = coded.join(''); return Plugin.raw === false || Plugin.utf8decode || utf8decode ? UTF8.decode(coded) : coded; }; module.exports = { btoa: Plugin.btoa, atob: Plugin.atob }
有時候後臺把圖片資源通過arrayBuffer傳給前端,這時候為了能正常顯示,我們還需要在轉化的base64字串前面拼接上data:image/jpeg;base64,
所以我們整理一下,可以得出這樣一個函數:
const { btoa } = require('./base64') const arrayBufferToBase64Img = (buffer) => { const str = String.fromCharCode(...new Uint8Array(buffer)); return `data:image/jpeg;base64,${btoa(str)}`; }
整個流程如下:
得到一個ArrayBuffer ---> 轉成型別化陣列以正常讀取(Uint8Array) --> 轉成普通字串(String.fromCharCode) --> 轉成base64字串(btoa)
到此這篇關於js如何實現小程式wx.arrayBufferToBase64方法範例的文章就介紹到這了,更多相關js實現小程式wx.arrayBufferToBase64內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45