wagng
wagng

Reputation: 711

How to convert base64 into Blob in React Native?

I am going to convert b64 to blob in react native.

But I am getting error on atob function.

Here are my codes.

var binary = atob(this.state.avatarSource.uri.split(',')[1]);
var byteNumbers = new Array(binary.length);

for(var i = 0; i < binary.length; i++) {
  byteNumbers.push(binary.charCodeAt(i));
}
var file = new Blob([new Uint8Array(byteNumbers)], {type: 'image/jpeg'});

Anybody has any idea?

Upvotes: 21

Views: 33058

Answers (7)

Sid
Sid

Reputation: 1014

Note that react native doesn't actually have Blobs - you can use the below code but note that the file will be loaded completely in memory so shouldn't be used for any large files. 'rn-fetch-blob' is the only library I have used that allows for native blobs - but it doesn't work with every package.

Note that the uri needs to be "file://path"

function uriToBlob(uri: string): Promise<Blob> {
return new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest()
  xhr.responseType = 'blob'
  xhr.onload = () => {
    const blob = xhr.response
    resolve(blob)
  }
  xhr.onerror = (err) => {
    reject(err)
  }
  xhr.open('GET', uri)
  xhr.send()
})}

Update: This also works for me

 const res = await fetch(`file://${segment.uri}`) 
 const blobData = await res.blob()

Update 2:

  static async resolveBlob(b: Blob | PolyfillBlob): Promise<ResolvedBlob> {
const blobToResolve = b as any
const resolvedBlob = await new Promise<ResolvedBlob>((resolve) => {
  if (blobToResolve.created) {
    resolve(blobToResolve)
  }

  blobToResolve.onCreated(() => {
    resolve(blobToResolve)
  })
})

resolvedBlob.created = true

// TODO: We need this because of https://github.com/RonRadtke/react-native-blob-util/issues/241
if (resolvedBlob.size === undefined) {
  const blobPath = resolvedBlob.getReactNativeBlobUtilRef()
  const { size } = await ReactNativeBlobUtil.fs.stat(blobPath)
  resolvedBlob.size = size
}

return resolvedBlob

}

Upvotes: 1

user938363
user938363

Reputation: 10378

Here is the conversion working on my RN 0.70.x:

import {decode, encode} from 'base-64';  //<<==yarn add base-64 if not available
// Convert base64 to blob 
    function base64ToUint8Array(base64) {
      try {      
        const binaryString = decode(base64); // Decode base64
        const len = binaryString.length;
        const bytes = new Uint8Array(len);
        for (let i = 0; i < len; i++) {
          bytes[i] = binaryString.charCodeAt(i);
        }
        return bytes;  //<<==blob
      } catch (err) {
        return null;
      };
    }

Upvotes: 0

o M a R
o M a R

Reputation: 11

right solution

1 = download this library npm i -S base-64

2= add this into import sction in your screen import {decode as atob, encode as btoa} from 'base-64';

3= set this function in your screen

  const dataURLtoFile = (dataurl, filename) => {
var arr = dataurl.split(','),
  mime = arr[0].match(/:(.*?);/)[1],
  bstr = atob(arr[1]),
  n = bstr.length,
  u8arr = new Uint8Array(n);

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

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

finally call this function

let file = dataURLtoFile(
                'data:image/png;base64,' + response.assets[0].base64, //if your bas64 include <data:image/png;base64,> rmove this from parameter 
                'test.png',
              );



console.log(file )

haaaa everything is ready

i hope this answer to help anyone

Upvotes: 1

BlueDevil2k6
BlueDevil2k6

Reputation: 156

Ran into this situation where fetch() on Android will not work with a data URI. Instead, try the following:

import { Buffer } from "buffer";


const base64 = 'iVBORw0KGgoAAAANSUhEU ....'
const buffer = Buffer.from(base64, "base64");

const blob = new Blob([buffer], { type: '[content-type]' })

content-type here would be 'image/png' if the base64 was a PNG file.

Upvotes: 7

Shabeer Ali
Shabeer Ali

Reputation: 1033

you could try fetch

  let blob = await this.base64ToBlob(encoded);
  console.log('btoB64 resp === ', blob);

  async base64ToBlob(encoded) {
    let url = `data:image/jpg;base64,${encoded}`;
    let res = await fetch(url);
    let blob = await res?.blob();
    return blob;
  }

Upvotes: -1

Xeijp
Xeijp

Reputation: 873

Do not use atob or btoa, that only works in Debug Mode.

Because when you're using Debug Mode, you're running your JS code in browser (which should be V8), whereas if you're going to run the app in production mode it uses JavascriptCore which does not have an atob or btoa implementation.

You can use base-64 to convert data to BASE64 encoded string, but I'm not sure if it can create a correct Blob object for you.

From my understanding, Blob is an bridge between JS context and file system, React Native does not have file system API itself yet, therefore you might get a Blob object but it's always empty.

If you're going to create an image from array contains numbers, you have a look at react-native-fetch-blob which is a project I'm working on, hopefully it can solve this kind of problems :)

Upvotes: 11

Jagadish Upadhyay
Jagadish Upadhyay

Reputation: 1264

I am getting the base 64 of an image. After that I am displaying it from below code. Hope it may help you

let imgSrc = "data:image/png;base64," + base64ImageData;
<Image source={{uri: imgSrc, scale: 1}} style={{ height: 80, width: 80}}/>

Upvotes: -1

Related Questions