木偶人截图保存图片数据的推荐方法是什么?

我正在制作一个应用程序,用于在地图上绘制运行的路线,并将它们保存到mongodb数据库中。

目前,我正在使用 puppeteer 来访问我的应用程序中的一条路线,并将坐标作为一个查询字符串传递给地图组件。一旦地图加载完毕,我就截图,将返回的Buffer转换为base64编码的字符串,保存到数据库中,然后用这个字符串在前端显示图片。

整个过程的中间件是这样的。

exports.screenshotMap = async (req, res, next) => {
  try {
    const { lineFeatures } = req.body;
    const browser = await puppeteer.launch({
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
    });

    // open new browser
    const page = await browser.newPage();

    // create array of coordinates from geojson features
    const coords = lineFeatures.map(line => line.geometry.coordinates);
    // reduce to 2D array of [lat, lon] coords
    const flattenedCoords = coords.reduce((accum, arr) => {
      return accum.concat(arr);
    }, []);
    // Stringify coords before using them as query string
    const coordsStr = JSON.stringify(flattenedCoords);

    // goto page with map sending coordintaes along
    await page.goto(`http://localhost:3000/test?coords=${coordsStr}`, {
      waitUntil: 'networkidle0',
    });

    // wait for map to load, call onLoad callback, and set state to make the h1 visible
   await page.waitForSelector('h1');
    // wait one more second to make sure all tiles for the map are loaded. Longer routes can require significantly more tiles
    await page.waitFor(1000);

    const image = await page.screenshot({
      type: 'jpeg',
      quality: 100,
      clip: {
        x: 0,
        y: 70,
        width: 640,
        height: 360,
      },
      omitBackground: true,
    });

    await browser.close();
    // convert buffer to base64 string
    const base64Image = await image.toString('base64');
    // attach to request object to be used in the next middleware
    req.image = base64Image;
    next();

  } catch (err) {
    res.status(400).send(err);
  }
};

这个方法是可行的,但是我想知道是否有更好的方法。我读到过存储Buffer数据对数据库内存的影响比较大,因为base64字符串非常长。更好的方法是保存Buffer数据,并在发送回客户端之前将其转换为编码字符串吗?有没有推荐的处理这类数据的方法?我很想听听别人的想法和方法。

解决方案:

我想到的解决方案是将截图返回的缓冲区保存到S3 bucket中,然后将唯一标识符url存储到我的数据库中。

下面是截图的中间件。

import puppeteer from 'puppeteer';
//import chromium from 'chrome-aws-lambda';

const takeMapImage = handler => async (req, res) => {
  try {
    const { lines } = req.body;

    // should work for most node projects
    const browser = await puppeteer.launch({
       args: ['--no-sandbox', '--disable-setuid-sandbox'],
    });

    // if youre using lambda functions
    // const browser = await chromium.puppeteer.launch({
    //  executablePath: await chromium.executablePath,
    // args: chromium.args,
    // defaultViewport: chromium.defaultViewport,
    // headless: chromium.headless,
    // });

    // open new browser
    const page = await browser.newPage();

    const url = 'https://yourwebstieurl.com';

    await page.goto(
      `${url}`,
      {
        waitUntil: 'networkidle0',
      }
    );

    // provide some waiting time if needed
    await page.waitFor(1000);

   // image buffer returned from screenshot
    const imageBuffer = await page.screenshot({
      type: 'jpeg',
      quality: 100,
      clip: {
        x: 0,
        y: 0,
        width: 640,
        height: 360,
      },
      omitBackground: true,
    });


    // attach to request object to be used in the next middleware
    req.buffer = imageBuffer;

    next();

  } catch (err) {
    console.log(err);
    return res
      .status(422)
      .send({ message: 'there was an error taking picture' });
  }
};

然后是将图片保存到S3的中间件。你需要创建一个 bucket,并获取凭证。

import AWS from 'aws-sdk';
import uuid from 'uuid/v1';

// create your s3instance with your credentials
const s3 = new AWS.S3({
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
});

const saveImageToS3 = handler => async (req, res) => {
  try {
    // use user id as identifier in S3 bucket
    const { id } = req.user;
    const { buffer } = req;

    // s3 file name
    const key = `${id}/${uuid()}.jpeg`;

    const params = {
      Bucket: 'your-bucket-name',
      Key: key,
      Body: buffer,
      ContentEncoding: 'base64',
      ContentType: 'image/jpeg',
    };

    // upload to bucket
    const response = await s3.upload(params).promise();
    // pass url to next middleware to save to db
    req.image = response.Location;
    next();
  } catch (e) {
    console.log(e);
    return res.status(422).json({ message: 'user error saving image to s3' });
  }
};

给TA打赏
共{{data.count}}人
人已打赏
未分类

如何为GKE集群创建Terraform代码?

2022-9-10 5:41:30

未分类

我应该使用什么RSA加密方法来生成JWT认证的签名?

2022-9-10 5:41:32

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索