2

I am trying to serve a base64 string as an image with image/png headers. The headers are being set properly but the images are not being shown all I can see is a blank screen. here is the code:

request('someCustomLink', function (error, response, body) {
// someCustomLink gives the base64 string
        var img = new Buffer(body, 'base64');
        res.writeHead(200, {
            'Content-Type': 'image/png',
            'Content-Length': img.length
        });
        res.end(img);         
});

this is the link that I followed to arrive at this solution.

Any help will be appreciated.

EDIT Here are the response headers from my someCustomLink (it might help in understanding the problem betr)

Accept-Ranges:bytes
Content-Length:128778
Content-Type:image-jpeg
Date:Thu, 21 Dec 2017 06:03:52 GMT
ETag:"edc04d469779108860478b361b7427d7"
Last-Modified:Mon, 11 Dec 2017 08:54:32 GMT
Server:AmazonS3
x-amz-id-2:QlR39g0vC5CeOo6fdKzX9uFB+uiOtj61c0LKW2rQLcCPWllcKyfbpg93Yido+vZfzMzB3lmhbNQ=
x-amz-request-id:3EC77634D9A05371

This is the get req

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

app.get('/thumb/:thumbLink', function(req, res) {


        request('https://s3.amazonaws.com/my-trybucket/projectImages/'+req.params.thumbLink, function (error, response, body) {
            //console.log('error:', error); // Print the error if one occurred
            //console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
            //console.log('body:', body); // Print the HTML for the Google homepage.
            var img = new Buffer(body, 'base64');
            res.writeHead(200, {
                'Content-Type': 'image/png'

            });
            res.end(img);
        });
    });

-Thanks

5
  • Why are you getting served a base64 PNG? That’s unusual. Commented Dec 21, 2017 at 5:54
  • I have an s3 bucket which contains images as base64 PNG. Commented Dec 21, 2017 at 5:56
  • Did you try logging body? Commented Dec 21, 2017 at 6:04
  • Yes tried it. It gives base64 string... Commented Dec 21, 2017 at 6:05
  • Here is the link that I am using s3.amazonaws.com/my-trybucket/projectImages/… Commented Dec 21, 2017 at 6:07

3 Answers 3

9

The response that you are getting contains data:image/png;base64,. You have remove this before creating the Buffer. See example below

request('https://s3.amazonaws.com/my-trybucket/projectImages/e31492f7314837a22a64395eee7cedfd', function(error, response, body) {
    var img = new Buffer(body.split(',')[1], 'base64');
    res.writeHead(200, {
      'Content-Type': 'image/png',
      'Content-Length': img.length 
    });
    res.end(img);
})
Sign up to request clarification or add additional context in comments.

5 Comments

But this Google logo is not base64. I have the customLink serving base64 strings that I need to convert to images. Also tried initializing the request as you told the results are the same all I am seeing is a blank image
Could you post a functional example?
added the functioning get req. you can replicate it on your system. find the link in the comment above
updated the answer. Also remove .defaults({ encoding: null }); as suggested earlier.
Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
0

Was stuck for long on this particular issue too only to find out that sending the actual data Body that comes back from s3 is actually sufficient to display the image. Here's my implementation (in typescript):

// a method in my Bucket class

async getObject(key: string) {
    const params = {
      Bucket: this.bucket, //my bucket name set in my constructor
      Key: key,
    };
    return new Promise((resolve, reject) => {
      s3.getObject(params, (err, data) => {
        if (err) reject(err);
        if(data) resolve(data.Body);
      });
    });
  }

// the get request route

app.get(
  "url/:folder/:id",
  async (req: Request, res: Response) => {
    const { folder, id } = req.params;
    const image = (await new Bucket().getObject(`${folder}/${id}`)) as Buffer;
    res.send(image);
  }
);

Comments

0

I got the error ECONNRESET on my server. It turned out that res.end() was responsible for it. I replaced it with res.send() and the transfer went without problems. Here is my generic solution for serving base64 files

async (req: Request, res: Response) => {
  const { id } = req.params;

  //Get the image or file with your own method
  const base64File = await GetBase64File(id)

  const [fileInfo, fileData] = base64File.split(",");
  const contentType = fileInfo.split(";")[0].replace("data:", "");

  res.setHeader("Content-Type", contentType);
  res.setHeader("Content-Length", fileData.length);

  const buffer = Buffer.from(fileData, "base64");
  res.send(buffer);
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.