简体   繁体   中英

How to Convert buffer into image using nodejs?

This is my code that I'm getting image from the S3 bucket but the results are in buffer I need that to be image. Please tell me to do that

const AWS = require('aws-sdk')
const fs = require('fs')
const express = require('express')
const app = express()
app.get('/', (req, res) => {
  const s3 = new AWS.S3({
    accessKeyId: '################',
    secretAccessKey: '###############################',
    region: '###########'
  })

  const params = {
    Bucket: '#########',
    Key: '########'
  }
  s3.getObject(params, (err, rest) => {
    res.send(rest)
  })
})

app.listen(3000)

OUTPUT

{
  AcceptRanges: 'bytes',
  LastModified: 2020-06-29T10:42:17.000Z,
  ContentLength: 338844,
  ETag: '"769af0d798cd0486993711bc63340bd0"',
  ContentType: 'application/octet-stream',
  Metadata: {},
  Body: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 84 00 02 02 02 
  02 02 02 02 02 02 02 03 03 02 03 03 04 03 03 03 03 04 06 04 04 04 ... 338794 
  more bytes>
}

TLDR;

/**
 * FINAL/WORKING SOLUTION
 */

// ...
app.get('/', (req, res) => {
  const s3 = new AWS.S3({
    accessKeyId: '-',
    secretAccessKey: '-',
    region: '-',
  });

  const params = {
    Bucket: '-',
    Key: '-',
  };

  s3.getObject(params, (err, rest) => {
    if (err) throw err;

    const b64 = Buffer.from(rest.Body).toString('base64');
    // CHANGE THIS IF THE IMAGE YOU ARE WORKING WITH IS .jpg OR WHATEVER
    const mimeType = 'image/png'; // e.g., image/png
    
    res.send(`<img src="data:${mimeType};base64,${b64}" />`);
  });
});
// ...

ORIGINAL ANSWER

You will need to use node to 'render' the image.. aka just send the response as an <img /> tag..

// ...
app.get('/', (req, res) => {
  const s3 = new AWS.S3({
    accessKeyId: '-',
    secretAccessKey: '-',
    region: '-',
  });

  const params = {
    Bucket: '-',
    Key: '-',
  };

  s3.getObject(params, (err, rest) => {
    if (err) throw err;

    const b64 = Buffer.from(rest).toString('base64');
    // NOTE: 
    // Because 'rest' appears to be a buffer, you might not 
    // need to do `Buffer.from(...)`,you may have to do something like:
    /** const b64 = rest.toString('base64'); **/
    const mimeType = 'image/png'; // e.g., image/png
    
    res.send(`<img src="data:${mimeType};base64,${b64}" />`);
  });
});
// ...

EDIT 1:

I believe the issue has something to do with how the data is returned to you from S3.. You may have to do something like rest.Body or rest.body - I am not sure what the object from S3 looks like.

With that being said, I saved this image locally as sample.png , and used the code below to load it - it worked just fine. This is proof the issue has something to do with how S3 is returning that data to you.

const fs = require('fs');
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  // Simulate getting data from S3 (aka data as buffer)
  const rest = Buffer.from(fs.readFileSync('./sample.png'));

  console.log('typeof rest = ' + typeof rest + '\r\n\r\n', rest);
  // typeof rest = object
  //
  // <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 34 00 00 00 a4 08 03 00 00 00 2e 4e 22 5a 00 00 00 a2 50 4c 54 45 f7 f7 f7 cd 00 00 d1 00 00 ... 6360 more bytes>


  const b64 = rest.toString('base64');
  const mimeType = 'image/png'; // e.g., image/png

  res.send(`<img src="data:${mimeType};base64,${b64}" />`);
});

app.listen(3000);

EDIT 2:

It looks like you'll need to do this:

// ...
app.get('/', (req, res) => {
  const s3 = new AWS.S3({
    accessKeyId: '-',
    secretAccessKey: '-',
    region: '-',
  });

  const params = {
    Bucket: '-',
    Key: '-',
  };

  s3.getObject(params, (err, rest) => {
    if (err) throw err;

    const b64 = Buffer.from(rest.Body).toString('base64');
    // IF THE ABOVE LINE DOES NOT WORK, TRY THIS:
    // const b64 = rest.Body.toString('base64');

    // CHANGE THIS IF THE IMAGE YOU ARE WORKING WITH IS .jpg OR WHATEVER
    const mimeType = 'image/png'; // e.g., image/png
    
    res.send(`<img src="data:${mimeType};base64,${b64}" />`);
  });
});
// ...

The first, let convert the buffer to string (in this case, we use base64 string) Then, return a simple html page to display base64 string image.

Follow the function will convert a buffer to a string

  const encode = (data) => {
    let buf = Buffer.from(data);
    let base64 = buf.toString('base64');
    return base64
  }

The send the html page to client:

    const html = `<html><body><img src='data:image/jpeg;base64,${encode(rest.Body)}'/></body></body></html>`
    res.send(html)

As you see, rest.Body is the buffer content of the image.

Final code:

const AWS = require('aws-sdk')
const fs = require('fs')
const express = require('express')
const app = express()
app.get('/', (req, res) => {
  const s3 = new AWS.S3({
    accessKeyId: '################',
    secretAccessKey: '###############################',
    region: '###########'
  })

  const params = {
    Bucket: '#########',
    Key: '########'
  }

  const encode = (data) => {
    let buf = Buffer.from(data);
    let base64 = buf.toString('base64');
    return base64
  }

  s3.getObject(params, (err, rest) => {
    const html = `<html><body><img src='data:image/jpeg;base64,${encode(rest.Body)}'/></body></body></html>`
    res.send(html)
  })
})

app.listen(3000)

1.Try using Jimp library to convert image to buffer,which can be saved in database as well.

 const imagePath = `path/to/image`;
  const jimpImageToBuffer = await jimp
    .read(imagePath) // read image from path
    .then((ele) => {
      const mimeForImage = ele._originalMime;
      return ele.getBufferAsync(mimeForImage); // convert image to buffer(compatiable to save to database).
    })
    .catch((err) => console.log(err));
  console.log(jimpImageToBuffer); // <- image in buffer format

check the below link for implementation and full explanation of jimp conversion of image to buffer.

https://stackoverflow.com/a/72798711/18383251

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM