Ma9ic
Ma9ic

Reputation: 1125

Display blob image in react native (Expo)

I have the following fetch function in my react native project to return a blob image from MS Graph, the return works but i cannot seem to display the blob as an image.

        //Blob Picture
      fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {
        headers: { 'Authorization': "Bearer " + accessToken },
      })
        .then((response) => {
          // console.log(response);
               this.setState({ BlobImage: response});
        })
        .catch((error) => {
          console.error(error);
        });

Then i wish to display the image like so:

   <Image source={{uri: BlobImage}} style={{ height: 200, width: null, flex: 1 }}/>

Upvotes: 0

Views: 5863

Answers (4)

Alan David Garcia
Alan David Garcia

Reputation: 1533

A utility method that converts the blob to base64 for setting the source of the Image component.

See below typescript example that downloads a blob from supabase storage and then converts the blob to base64 to display using expo-image:


/**
 * fetcher to convert from blob to base 64 to be rendered,
 *
 * @param path
 */
export const downloadImageBlobAndConvert = async (path: string) => {
  const { data: blob, error } = await supabase.storage
    .from("avatars")
    .download(path);

  if (error) throw error;

  // convert blob to base64 string
  return new Promise<string>((resolve) => {
    const fileReaderInstance = new FileReader();
    fileReaderInstance.readAsDataURL(blob as Blob);
    fileReaderInstance.onload = () => {
      resolve(fileReaderInstance.result as string);
    };
  });
};


const url = await downloadImageBlobAndConvert(pet.avatar_url).catch(() => null)   

Then to render with expo-image

<Image source={url} />

Upvotes: 0

Chris
Chris

Reputation: 1829

After a lot of wasted time, this works well with React Native > 0.60 and Expo using react-native-image-picker or expo-image-picker and axios.

const {uri} = file;
const uriParts = uri.split('.');
const fileType = 'image/' + uriParts[uriParts.length - 1];

const data = new FormData();
data.append('image', {type: fileType, uri: uri, name: 'image'});
data.append('first_name', 'John Doe')

const req = await axios.post(url, data, {headers: {'Content-Type': 'multipart/form-data'} });

Upvotes: 0

Gondim
Gondim

Reputation: 3048

Although there is an answer already for this and it is marked as resolved, I'm adding here my solution.

I have tried react-native-fetch-blob without success.

Initially I set the responseType to be 'arraybuffer'

const photo = await graph.get('/me/photo/$value', {
      responseType: 'arraybuffer'
    });

Now the response has an arraybuffer in photo.data

const state = {
            photo: photo.data
};

On my Screen, I have displayed the image making use of the package base64-arraybuffer.

import Base64ArrayBuffer from 'base64-arraybuffer';
...
const photoURI = Base64ArrayBuffer.encode(state.photo);
...
<Image style={styles.profilePhoto} source={{ uri: `data:image/jpg;base64,${photoURI}` }} />

Upvotes: 1

Ali Bakhtiar
Ali Bakhtiar

Reputation: 178

One way is to convert your blob into base64 and use it as uri as described here But I would rather to use rn-fetch-blob and using path since is more straight forward. check this example:

RNFetchBlob
  .config({
    fileCache : true,
    // by adding this option, the temp files will have a file extension
    appendExt : 'png'
  })
  .fetch('GET', 'http://www.example.com/file/example.zip', {
    //some headers ..
  })
  .then((res) => {
    // the temp file path with file extension `png`
    console.log('The file saved to ', res.path())
    // Beware that when using a file path as Image source on Android,
    // you must prepend "file://"" before the file path
    imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
  })

Upvotes: 0

Related Questions