用 Node.js 渲染优化图像并用 sharp 或 canvas 表达
Render opmised images with Node.js and express with sharp or canvas
我正在努力使用 node 和 express 以优化配置渲染图像 sharp。
我设法使用 Jimp 创建了一个上传方法,可以转换大于 2000px 宽和大于 2mb 文件大小的图像,并且工作正常,我遇到了几十个做同样的库 Jimp 在内存中更有效我建了。
基本上我的液体模板引擎是这样的:
<img src="{{i.images[0].path}}" alt="{{i.name}}">
我想创建一个路由器,它使用图像数组从 MongoDB /projects/project 路径读取图像,并将图像传回渲染器,按照配置中的说明进行优化和调整大小sharp,我想进一步将此方法配置为一个中间件,以便在站点中全局工作,使用带有查询参数的图像按需呈现,同时通过设备检测进行增强以获得更好的性能下载:
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 会很好用,请给我一些想法。
问题已解决 here 感谢 Sharp 的 Lovell 创建者。
为了渲染清晰的图像并将其正确地通过管道传递给响应,在这种情况下,您只传递了 Sharp 及其可配置函数的变压器,看起来我正试图再次将图像传递给变压器,而这returns 一个错误 可写流上的意外数据
我对此代码进行了各种更改,并选择创建一个中间件来在我的应用程序中处理此问题。
我使用的最终代码如下所示:
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 和 express 以优化配置渲染图像 sharp。
我设法使用 Jimp 创建了一个上传方法,可以转换大于 2000px 宽和大于 2mb 文件大小的图像,并且工作正常,我遇到了几十个做同样的库 Jimp 在内存中更有效我建了。
基本上我的液体模板引擎是这样的:
<img src="{{i.images[0].path}}" alt="{{i.name}}">
我想创建一个路由器,它使用图像数组从 MongoDB /projects/project 路径读取图像,并将图像传回渲染器,按照配置中的说明进行优化和调整大小sharp,我想进一步将此方法配置为一个中间件,以便在站点中全局工作,使用带有查询参数的图像按需呈现,同时通过设备检测进行增强以获得更好的性能下载:
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 会很好用,请给我一些想法。
问题已解决 here 感谢 Sharp 的 Lovell 创建者。
为了渲染清晰的图像并将其正确地通过管道传递给响应,在这种情况下,您只传递了 Sharp 及其可配置函数的变压器,看起来我正试图再次将图像传递给变压器,而这returns 一个错误 可写流上的意外数据
我对此代码进行了各种更改,并选择创建一个中间件来在我的应用程序中处理此问题。
我使用的最终代码如下所示:
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;
如果你遇到这个问题,你需要更多地了解节点文件系统、流和管道函数它们是如何工作的,才能完全理解你在做什么。 ;-)