J'ai reçu une communication webSocket, je reçois une chaîne encodée en base64, je la convertis en uint8 et je travaille dessus, mais maintenant, je dois renvoyer, j'ai le tableau uint8 et le convertir en chaîne base64 afin de pouvoir l'envoyer. Comment puis-je faire cette conversion?
Si vos données peuvent contenir des séquences multi-octets (pas une séquence simple ASCII)) et que votre navigateur dispose de TextDecoder , utilisez-le pour décoder vos données (spécifiez le codage requis pour le TextDecoder):
var u8 = new Uint8Array([65, 66, 67, 68]);
var decoder = new TextDecoder('utf8');
var b64encoded = btoa(decoder.decode(u8));
Si vous avez besoin de support navigateurs sans TextDecoder (actuellement IE et Edge), la meilleure option est d’utiliser un TextDecoder Polyfill .
Si vos données contiennent des caractères simples ASCII (pas Unicode multi-octets/UTF-8), il existe une alternative simple: String.fromCharCode
qui devrait être assez universellement supporté:
var ascii = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(String.fromCharCode.apply(null, ascii));
Et pour décoder la chaîne base64 en Uint8Array:
var u8_2 = new Uint8Array(atob(b64encoded).split("").map(function(c) {
return c.charCodeAt(0); }));
Si vous avez de très grands tampons de tableau, l’application peut échouer et vous devrez peut-être découper le tampon (en fonction de celui publié par @RohitSengar). Encore une fois, notez que ceci n’est correct que si votre tampon ne contient que des caractères non multi-octets ASCII caractères:
function Uint8ToString(u8a){
var CHUNK_SZ = 0x8000;
var c = [];
for (var i=0; i < u8a.length; i+=CHUNK_SZ) {
c.Push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ)));
}
return c.join("");
}
// Usage
var u8 = new Uint8Array([65, 66, 67, 68]);
var b64encoded = btoa(Uint8ToString(u8));
function Uint8ToBase64(u8Arr){
var CHUNK_SIZE = 0x8000; //arbitrary number
var index = 0;
var length = u8Arr.length;
var result = '';
var slice;
while (index < length) {
slice = u8Arr.subarray(index, Math.min(index + CHUNK_SIZE, length));
result += String.fromCharCode.apply(null, slice);
index += CHUNK_SIZE;
}
return btoa(result);
}
Vous pouvez utiliser cette fonction si vous avez un très grand Uint8Array. Ceci est pour Javascript, peut être utile dans le cas de FileReader readAsArrayBuffer.
Solution très simple et test pour JavaScript!
ToBase64 = function (u8) {
return btoa(String.fromCharCode.apply(null, u8));
}
FromBase64 = function (str) {
return atob(str).split('').map(function (c) { return c.charCodeAt(0); });
}
var u8 = new Uint8Array(256);
for (var i = 0; i < 256; i++)
u8[i] = i;
var b64 = ToBase64(u8);
console.debug(b64);
console.debug(FromBase64(b64));
EDIT 2019: J'ai passé en revue ceci et ceci n'est pas une solution pour envoi d'images, uniquement en les affichant localement. Le createObjectURL
ne crée pas de données base64, mais un DOMString
, qui est simplement une courte URL spécifique au navigateur que vous pouvez utiliser dans img.src
ou similaire.
Je vais ajouter une autre solution qui fonctionne avec des plages non imprimables. C'est beaucoup plus rapide que de chaîner TextEncoder
et btoa
alors que tout ce dont vous avez besoin est d'afficher une image reçue sous forme de tableau d'octets.
var blob = new Blob( [ uint8ArrayBuffer ], { type: "image/jpeg" } );
var imageUrl = URL.createObjectURL( blob );
Ceci utilise des API HTML5 et ne fonctionnera donc pas sur Node ou d'autres serveurs basés sur JS, bien sûr. Vous pouvez voir une démo ici .
Voici une fonction JS à ceci:
Cette fonction est nécessaire car Chrome n'accepte pas encore une chaîne codée en base64 comme valeur pour applicationServerKey dans pushManager.subscribe https://bugs.chromium.org/p/chromium/ issues/detail? id = 80228
function urlBase64ToUint8Array(base64String) {
var padding = '='.repeat((4 - base64String.length % 4) % 4);
var base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
var rawData = window.atob(base64);
var outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
(Décodez une chaîne Base64 en Uint8Array ou ArrayBuffer avec le support Unicode)
Toutes les solutions déjà proposées ont de graves problèmes. Certaines solutions ne fonctionnent pas avec les tableaux de grande taille, certaines fournissent une sortie incorrecte, certaines génèrent une erreur lors d’un appel btoa si une chaîne intermédiaire contient des caractères multi-octets, d’autres utilisent davantage de mémoire que nécessaire.
J'ai donc implémenté une fonction de conversion directe qui fonctionne indépendamment de l'entrée. Il convertit environ 5 millions d'octets par seconde sur ma machine.
https://Gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
Si vous utilisez Node.js, vous pouvez utiliser ce code pour convertir Uint8Array en base64
var b64 = Buffer.from(u8).toString('base64');