Download an image using Axios and convert it to base64
Asked Answered
H

6

152

I need to download a .jpg image from a remote server and convert it into a base64 format. I'm using axios as my HTTP client. I've tried issuing a git request to the server and checking the response.data however it doesn't seem to work like that.

Link to axios: https://github.com/mzabriskie/axios

Link to base64 implementation: https://www.npmjs.com/package/base-64

I'm using NodeJS / React so atob/btoa doesn't work, hense the library.

axios.get('http://placehold.it/32').then(response => {
    console.log(response.data); // Blank
    console.log(response.data == null); // False 
    console.log(base64.encode(response.data); // Blank
}).catch(err => console.log(err));
Hausmann answered 25/1, 2017 at 8:29 Comment(1)
Have you tried to change responseType to say blob? From docs "// responseType indicates the type of data that the server will respond with"Twayblade
P
363

This worked great for me:

function getBase64(url) {
  return axios
    .get(url, {
      responseType: 'arraybuffer'
    })
    .then(response => Buffer.from(response.data, 'binary').toString('base64'))
}
Pretense answered 18/5, 2017 at 22:27 Comment(10)
This works perfectly well! I would upvote 100 times if I could!Ellery
if you're using react-native, add this to the top of your files: global.Buffer = global.Buffer || require('buffer').BufferSylvestersylvia
Thank you, works great! If you're putting the base64 in <img src="" ... then don't forget to prefix the base64 string with "data:image/jpeg;base64, "Heng
DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.Khamsin
that should be Buffer.from(response.data, 'binary'))Khamsin
can you imagine I spent about 5+ hours trying to find out why the file wasn't loading correctlyTennessee
Where can I find documentation about Buffer.from?Destitution
This can break on requests, that return something other than image (e.g. HTML page with successful status code, e.g. from redirect). A check wheather the buffer is an actual image, would be needed.Reason
for you working with react-script v5, you must install buffer dependency first. and import it. npm install bufferJourneywork
A Big Thanks to the questioner and answerer! A little thing but it saved a lot of hours of efforts. The answer should be marked as an accepted answer.Woolridge
F
38

There might be a better way to do this, but I have done it like this (minus the extra bits like catch(), etc.):

axios.get(imageUrl, { responseType:"blob" })
    .then(function (response) {

        var reader = new window.FileReader();
        reader.readAsDataURL(response.data); 
        reader.onload = function() {

            var imageDataUrl = reader.result;
            imageElement.setAttribute("src", imageDataUrl);

        }
    });

I have a suspicion that at least part of your problem might be server-side. Even without setting { responseType: "blob" } you should have had something in your response.data output.

Fasto answered 21/3, 2017 at 13:23 Comment(2)
after searching for hours I found the solution. Thank you!!Magical
Very nice, thank you. Something for others to pay attention to is needing to attach an event listener to load. This is essential for getting the result after reading the data into the FileReader isntance.Puritanical
E
28

This is what works for me (with Buffer.from) -

axios
  .get(externalUrl, {
    responseType: 'arraybuffer'
  })
  .then(response => {
    const buffer = Buffer.from(response.data, 'base64');
  })
  .catch(ex => {
    console.error(ex);
  });
Ersatz answered 26/6, 2019 at 23:5 Comment(2)
responseType: 'arraybuffer' was what needed in my case!Cooperage
responseType: 'arraybuffer' and Buffer.from(response.data, 'binary') for download the pdf file.Caucasus
E
8

using responseType: "text", responseEncoding: "base64" will get response body encoded as base64 string

for example, the sample code will get base64 and write a jpg file to disk.

import axios from "axios";
import fs from "fs";

axios
  .get("https://picsum.photos/255", {
    responseType: "text",
    responseEncoding: "base64",
  })
  .then((resp) => {
    console.log(resp.data);
    fs.writeFileSync("./test.jpg", resp.data, { encoding: "base64" });
  })
Emmyemmye answered 25/8, 2022 at 9:21 Comment(0)
H
3

You can convert the blob to base64 from FileReader api and then display it.

 const fileReaderInstance = new FileReader();
 fileReaderInstance.readAsDataURL(blob); 
 fileReaderInstance.onload = () => {
 base64data = fileReaderInstance.result;                
 console.log(base64data);
 }

and display it as:

   <Image source={{uri: base64ImageData}} />
Humility answered 16/7, 2021 at 1:54 Comment(1)
OP requested axios, otherwise that's a great solution for the browser!Coonan
A
3
import { Axios } from "axios";

const axios = new Axios({});

const res = await axios.get(url, {
  responseType: "text",
  responseEncoding: "base64",
});

const base64 = Buffer.from(res.data, "base64");
Affected answered 19/11, 2022 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.