0

我正在努力使用 node 和 express 以优化配置渲染图像

我设法使用 Jimp 创建了一个上传方法,该方法可以转换大于 2000px 宽和大于 2mb 文件大小的图像,并且效果很好,我遇到了许多执行相同操作的库 Jimp 对于我构建的内容在内存中的效率更高。

基本上我在我的液体模板引擎中有这样的:

<img src="{{i.images[0].path}}" alt="{{i.name}}">

我想创建一个路由器,它使用 images 数组从 MongoDB /projects/project 路由中读取图像,并将图像传递回渲染器,按照配置中的指示优化和调整大小,我想进一步配置此方法可能是一个中间件,可以在站点中全局使用带有查询参数的图像,以便按需渲染,还可以通过设备检测来增强下载性能:

const request = require('request');
const fs = require("fs");
const path = require("path");
const sharp = require('sharp');

module.exports = (req, res, next) => {

    request(process.env.REQUEST_PATH + "/projects?projectType=Refurbishment%20and%20Extensions", (err, response, body) => {
        if (err) {
            console.log(err);
        } else {

            const contentData = JSON.parse(body);

            contentData.projects.forEach((value, key) => {
                if (value.images[0].path.length > 0) {
                    const readStream = fs.createReadStream(path.resolve("./" + value.images[0].path));
                    //const getBuffer = Buffer.from(path.resolve("./" + value.images[0].path));
                    const trasnform = sharp(readStream).resize(200, 200, {
                        fit: "contain"
                    }).jpeg({
                        quality: 20
                    }).toBuffer((err, data, info) => {
                        if (err) {
                            console.log(err)
                        } else {
                            console.log("BUFFERED RESIZED", info);
                            //console.log("BUFFER", data);
                        }
                    });
                    console.log(trasnform); //nothing working
                    readStream.pipe(trasnform).pipe(res);
                }
            });

            const data = {
                name: "Refurbishment and Extensions Projects",
                content: contentData
            };

            res.render('./refurbishment-and-extensions-projects', {
                page: data
            });

        }
    });

}

在某些尝试中,它从 Sharp 返回信息并将图像转换为缓冲区,我不知道为什么,但现在我收到错误 [错误:输入文件丢失] 但有一个缓冲区要读取!

目前我对解决方案并不挑剔,但关于一些性能测试,sharp.js 或 canvas.js 会很好用,请给我一些想法。

4

1 回答 1

1

感谢 Sharp 的 Lovell 创建者,问题在这里得到了解决。

为了以清晰的方式渲染图像并将其正确传递给响应,在这种情况下您只传递变压器 Sharp 及其可配置的功能,看起来我试图再次将图像传递给变压器,这会返回错误Unexpected data在可写流上

我对此代码进行了各种更改,并选择创建一个中间件来在我的应用程序中处理它。

我使用的最终代码如下所示:

const express = require("express");
const router = express.Router();
const fs = require("fs");
const path = require("path");
const Sharp = require('sharp');

router.get('/:imageName', (req, res, next) => {

    const imagePath = "./" + req._parsedOriginalUrl.pathname; //req.originalUrl or req._parsedOriginalUrl.pathname

    if (req.query.format != null) {

        if (fs.existsSync(imagePath)) {

            const format = req.query.format ? req.query.format : "webp";
            const width = req.query.width ? parseInt(req.query.width) : null;
            const height = req.query.height ? parseInt(req.query.height) : null;
            const crop = req.query.crop ?  req.query.crop : "cover";

            const stream = fs.createReadStream(imagePath);

            const transform = Sharp().resize(width, height, {
                fit: crop
            }).toFormat(format, {
                quality: 85
            });

            res.set('Content-Type', `image/${format}`);
            stream.pipe(transform).pipe(res);

            return stream;

        }//ensuring the file path is correct
    }
    next();
});

module.exports = router;

如果你遇到这个问题,你需要更多地了解 Node Filesystem、Streams 和 pipe 函数它们是如何工作的,才能完全理解你在做什么。;-)

于 2019-02-18T12:26:35.727 回答