admin管理员组

文章数量:814981

从Node.js和Mongoose中的二进制文件重新创建图像

我正在努力在Node.js中创建上传/下载图像功能。到目前为止,有POST请求将图像保存为MongoDB中的二进制文件,还有GET请求将图像返回。但是我不知道如何使用该响应,它是一个数字数组,也不知道如何转换它。

这里是Mongo模型:

image.jsconst mongoose = require('mongoose');const Schema = mongoose.Schema;

const ImageItem = new Schema({
  id: {
    type: String
  },
  value: {
    type: Buffer
  },
});

module.exports = Image = mongoose.model('image', ImageItem);

POST图像在数据库中创建一个条目:

const image = require('../models/image');
const user = require('../models/user');

const multer = require('multer');
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname + new Date().toISOString());
  },
});


const upload = multer({
  storage: storage,
});

module.exports = function (app) {
  app.post('/upload', upload.single('value'), (req, res, next) => {
    const newImage = new image({
      id: req.body.id,
      value: req.file.path,
    });
    newImage
      .save()
      .then((result) => {
        console.log(result);
        res.status(201).json({
          message: 'created succesfully',
        });
      })
      .catch((err) => {
        console.log(err);
        res.status(500).json({
          error: err,
        });
      });
  });
};

以及在数据库中创建的条目:

为了获得我创建的GET请求的图像:

const image = require('../ models / image');

module.exports = function (app) {
  app.get('/upload/:id', (req, res) => {
    console.log('req.body.id', req.params);
    image.find({ id: req.params.id }, function (err, results) {
      if (err) {
        res.send(`error: ${err}`);
      } else {
        res.send(results);
      }
    });
  });
};

在Postman中测试的返回一个包含数字数组的JSON:

[
    {
        "_id": "5ebd1c112892f4230d2d4ab4",
        "id": "[email protected]",
        "value": {
            "type": "Buffer",
            "data": [
                117,
                112,
                108,
                111,
                97,
                100,
                115,
                47,
                117,
                115,
                101,
                114,
                80,
                105,
                99,
                116,
                117,
                114,
                101,
                46,
                112,
                110,
                103,
                50,
                48,
                50,
                48,
                45,
                48,
                53,
                45,
                49,
                52,
                84,
                49,
                48,
                58,
                50,
                51,
                58,
                49,
                51,
                46,
                57,
                51,
                52,
                90
            ]
        },
        "__v": 0
    }
]

如何使用此数据获取实际图像?

回答如下:

您可以从该数组创建一个Buffer

const imageBuffer = Buffer.from(row.value.data); // [117, 112, 108...]

无论如何检查ImageItem模式,row.value都将是Buffer

现在您需要做的就是设置正确的content-type并使用Buffer响应res.send而不是猫鼬模式。

app.get('/upload/:id', (req, res) => {
    console.log('req.body.id', req.params);
    image.find({ id: req.params.id }, function (err, results) {
      if (err) {
        res.send(`error: ${err}`);
      } else {
        const [row] = results;
        res.header('Content-Type', 'image/png');
        res.send(row.value);
      }
    });
});

如果您不知道Content-Type,则可以使用file-type包从Buffer中获取它。

const { mime } = fileType(row.value)

由于只获取特定图像,因此您可能需要使用.findOne而不是.find


现在还有其他问题,您正在存储文件路径,而不是所需的二进制映像。

您发布的那些字节等于:uploads/userPicture.png2020-05-14T10:23:13.934Z"

const data = new TextDecoder().decode(new Uint8Array([117,112,108,111,97,100,115,47,117,115,101,114,80,105,99,116,117,114,101,46,112,110,103,50,48,50,48,45,48,53,45,49,52,84,49,48,58,50,51,58,49,51,46,57,51,52]))

console.log(data);

本文标签: 从Nodejs和Mongoose中的二进制文件重新创建图像