Приложение - вывод времени, даты и некоторой доп. инфы с использованием рандомных картинок для фона.
Примерный вид:
Суть:
Как переделать данное NodeJS приложение под возможность использования нескольких конфигов (к примеру - использование рекурсивно конфиги из папки ./configs) и путей в url-адресе (указываемом в конфигах)?
Т.е.
./configs/config1.js -> address.com/generate1.jpg
./configs/config2.js -> address.com/generate2.jpg
./configs/config3.js -> address.com/generate3.jpg
...
Само приложение:const GIFEncoder = require('gifencoder');
const pngFileStream = require('png-file-stream');
const Promise = require('bluebird');
const Jimp = require('jimp');
const fs = require('fs');
const gm = require('gm');
const path = require('path');
const express = require('express');
const random = require('d3-random');
const app = express();
const width = 800;
const height = 325;
const encoder = new GIFEncoder(width, height);
const now = () => new Date();
const leadZeros = (value, count) => {
value = value ? value.toString() : '';
while (count > value.length) {
value = '0' + value;
}
return value;
}
const widgets = {
overlay: (canvas, options) => {
const file = path.resolve(options.image);
return canvas.draw([`image Over ${options.x},${options.y} ${options.width},${options.height} ${file}`]);
},
time: (canvas, options) => {
return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
.fill(options.fontColor || '#eee')
.gravity('Center')
.drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), `${leadZeros(now().getHours(), 2)}:${leadZeros(now().getMinutes(), 2)}`);
},
date: (canvas, options) => {
return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
.fill(options.fontColor || '#eee')
.gravity('Center')
.drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), `${leadZeros(now().getDate(), 2)}/${leadZeros(now().getMonth() + 1, 2)}`);
},
text: (canvas, options) => {
return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
.fill(options.fontColor || '#eee')
.gravity('Center')
.drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), options.text);
},
quality: (canvas, options) => {
return canvas
.quality(options.value);
}
};
const config = {
widgets: [
{ type: 'time', options: { x: 150, y: height - 150 } },
{ type: 'date', options: { x: width - 150, y: height - 150 } },
{ type: 'quality', options: { value: 80 } },
]
};
const preprocess = (dirName, fileName) => {
const defer = new Promise((resolve, reject) => {
const inputPath = path.join(dirName, fileName);
let canvas = gm(inputPath);
for (let i = 0; i < config.widgets.length; i++) {
const widget = config.widgets[i];
if (widgets[widget.type]) {
canvas = widgets[widget.type](canvas, widget.options);
}
else {
console.error(`Widget '${widget.type}' is not defined. Check your configuration declaration`);
}
}
canvas.toBuffer('JPG', (err, buffer) => {
resolve(buffer);
});
});
return defer;
};
const randomizer = random.randomUniform(0, fs.readdirSync('./frames').length);
const generate = () => {
const filename = fs.readdirSync('./frames')[Math.floor(randomizer())];
return preprocess('./frames', filename);
};
let cache = null;
let cachedResult = null;
app.get('/generate', function (req, res) {
if (!cache || cache < new Date().getTime()) {
cache = new Date().getTime() + 10000;
cachedResult = generate();
}
cachedResult.then(result => {
res.header('Content-Type', 'image/png');
res.end(result);
// fs.writeFile('img.jpg', result, (err) => {
// });
});
});
generate().then(() => {
app.listen(3000, function () {
console.log(`Img is running on:: 3000!`);
});
});
Зависимости:
{
"dependencies": {
"bluebird": "^3.5.1",
"d3-random": "^1.1.0",
"express": "^4.16.2",
"gm": "^1.23.0"
},
"devDependencies": {
"@types/bluebird": "^3.5.3",
"typescript": "^2.3.2"
}
}