Node.js get image from web and encode with base64

126,141

Solution 1

BufferList is obsolete, as its functionality is now in Node core. The only tricky part here is setting request not to use any encoding:

var request = require('request').defaults({ encoding: null });

request.get('http://tinypng.org/images/example-shrunk-8cadd4c7.png', function (error, response, body) {
    if (!error && response.statusCode == 200) {
        data = "data:" + response.headers["content-type"] + ";base64," + Buffer.from(body).toString('base64');
        console.log(data);
    }
});

Solution 2

If anyone encounter the same issue while using axios as the http client, the solution is to add the responseType property to the request options with the value of 'arraybuffer':

let image = await axios.get('http://aaa.bbb/image.png', {responseType: 'arraybuffer'});
let returnedB64 = Buffer.from(image.data).toString('base64');

Hope this helps

Solution 3

LATEST, AS OF 2017 ENDING

Well, after reading above answers and a bit research, I got to know a new way which doesn't require any package installation, http module(which is built-in) is enough!

NOTE: I have used it in node version 6.x, so I guess its also applicable to above versions.

var http = require('http');

http.get('http://tinypng.org/images/example-shrunk-8cadd4c7.png', (resp) => {
    resp.setEncoding('base64');
    body = "data:" + resp.headers["content-type"] + ";base64,";
    resp.on('data', (data) => { body += data});
    resp.on('end', () => {
        console.log(body);
        //return res.json({result: body, status: 'success'});
    });
}).on('error', (e) => {
    console.log(`Got error: ${e.message}`);
});

I hope it helps!

Also, check more about the http.get(...) here !

Solution 4

If you know the image type, it's a one-liner with the node-fetch package. Might not suit everyone, but I already had node-fetch as a dependency, so in case others are in a similar boat:

await fetch(url).then(r => r.buffer()).then(buf => `data:image/${type};base64,`+buf.toString('base64'));

Solution 5

If you are using axios then you can follow below steps

var axios = require('axios');
const url ="put your url here";
const image = await axios.get(url, {responseType: 'arraybuffer'});
const raw = Buffer.from(image.data).toString('base64');
const base64Image = "data:" + image.headers["content-type"] + ";base64,"+raw;

you can check with decode base64.

Share:
126,141

Related videos on Youtube

Aleksr9
Author by

Aleksr9

Updated on April 16, 2022

Comments

  • Aleksr9
    Aleksr9 about 2 years

    I'm trying to fetch an image from the web and encode it with base64.

    what i have so far is basically:

    var request = require('request');
    var BufferList = require('bufferlist').BufferList;
    
    bl = new BufferList(),
    
    request({uri:'http://tinypng.org/images/example-shrunk-8cadd4c7.png',responseBodyStream: bl}, function (error, response, body) 
    {
        if (!error && response.statusCode == 200) 
        {
            var type = response.headers["content-type"];
            var prefix = "data:" + type + ";base64,";
            var base64 = new Buffer(bl.toString(), 'binary').toString('base64');
            var data = prefix + base64;
            console.log(data);
        }
    });
    

    This seems to be pretty close to the solution but i can't quite get it to work. It recognizes the data type and gives out the output:

    data:image/png;base64
    

    however the bufferlist 'bl' seems to be empty.

    Thanks in advance!

    • Brett Zamir
      Brett Zamir almost 11 years
      Just a completely wild guess but I think it could be possible that the request() may be using a header indicating an agent that may be blocked by certain sites to minimize scraping.
    • Sebastian vom Meer
      Sebastian vom Meer almost 11 years
      @BrettZamir Do you think so? Blocking a request with a 200 response seems very nasty...
    • Sebastian vom Meer
      Sebastian vom Meer almost 11 years
      And may I ask: What is require('request')? Cannot find it in the documentation. All I know for this is http/https.
    • Brett Zamir
      Brett Zamir almost 11 years
      @Sebastian, yes, it is just a wild guess... But it is one of those problems which has recurred for me, so just offering it as a throwaway...
    • gustavohenke
      gustavohenke almost 11 years
      @SebastianG, if you can't find something being required in the docs, then that means it's from...? :D
    • Sebastian vom Meer
      Sebastian vom Meer almost 11 years
      @gustavohenke Sorry, I don't get it...
  • Aleksr9
    Aleksr9 almost 11 years
    Great it worked, thanks!. One question though, why does request not be set to any encoding? I still get some sort of result if i skip the .defaults({ encoding: null }) part.
  • Dan Kohn
    Dan Kohn almost 11 years
    encoding: null tells request that you want a buffer, not a string. A string gives you unusably garbled data, as the whole point of base64 is to encode binary. I got the answer about encoding in my own StackOverflow question stackoverflow.com/questions/16619980/…, so I'm happy to pay it forward.
  • Omar Meky
    Omar Meky over 9 years
    Works fine on localhost but getting ECONNREFUSED in production. Any ideas?
  • Semur Nabiev
    Semur Nabiev over 6 years
    base64.encode(<URL>, <OPTIONS>, <CALLBACK>) api reference: github.com/riyadhalnur/node-base64-image/blob/HEAD/docs/docs‌​.md
  • l p
    l p over 6 years
    This works. I had to use both the http and https modules in my solution since most resources are https today. Unfortunately, you'll need to check manually which module to use. See stackoverflow.com/a/45215071/4978821.
  • Valfar Developer
    Valfar Developer over 6 years
    Best answer for me!
  • SouvikMaji
    SouvikMaji about 5 years
    Solution: Run production from localhost
  • Dimas Crocco
    Dimas Crocco about 5 years
    May all Gods bless you... I knew it was an encoding problem, but I was struggling to find how to disable it on request library...
  • Nagendra Rao
    Nagendra Rao over 4 years
    @DanKohn new Buffer is now deprecated. nodejs.org/api/buffer.html
  • Dhananjai Pai
    Dhananjai Pai over 4 years
    Thank you so much! Helped me saved a bunch of time and frustration!
  • ShaneTheKing
    ShaneTheKing over 3 years
    I was having a lot of issues with this and axios, turns out the response type is what makes it. Thansk a lot!
  • Casimir
    Casimir over 3 years
    Nice and concise!
  • Gus
    Gus over 2 years
    Works well! .buffer has been deprecated. This is the new way: const blob = await response.arrayBuffer(); return `data:${response.headers.get("content-type")};base64,${Buffe‌​r.from(blob).toStrin‌​g("base64")}`;
  • kibuikaCodes
    kibuikaCodes about 2 years
    request is also deprecated