Skip to content

Instantly share code, notes, and snippets.

@karlwilcox
Created September 28, 2023 14:08
Show Gist options
  • Save karlwilcox/78d49a2795e9f6abae2900a3b5203797 to your computer and use it in GitHub Desktop.
Save karlwilcox/78d49a2795e9f6abae2900a3b5203797 to your computer and use it in GitHub Desktop.
Node.js Image Conversion Services over HTTP
// receive POST to /convert, with POST fields:
// svg - SVG image data
// format - format to convert image to (see switch below)
// width - width of converted image in pixels
// height - height of converted image in pixels
const express = require('express');
const multer = require('multer');
const upload = multer({ limits:{fieldSize: 25 * 1024 * 1024} });
const sharp = require("sharp");
const host = 'localhost';
const port = 3000; // no need to open in firewall if accessed locally only
const defaultWidth = 500; // adjust to suit, these are for DrawShield
const defaultHeight = 600;
const debug = false;
const app = express();
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html"); // Suggested contents, usage instructions?
});
app.post('/convert', upload.none(), (req, res) => {
if (debug) {console.log(req.body);}
let format = req.body.format;
let width = Number(req.body.width);
let height = Number(req.body.height);
let options = {};
switch(format.toLowerCase()) {
case 'jpeg':
case 'jpg':
format = 'jpeg';
options = { quality: 90 };
break;
case 'webp':
format = 'webp';
options = { lossless: true };
break;
case false: // i.e. undefined
case 'png':
format = 'png';
break;
default:
res.setHeader("Content-Type", "text/plain");
res.writeHead(500);
res.end("Unknown conversion format");
return;
}
if (!width) {
width = defaultWidth;
} else if (width < 50) {
width = 50;
}
if (!height) {
height = defaultHeight;
} else if (height < 50) {
height = 50;
}
let svg = req.body.svg;
// just a dummy box if for some reason we get nothing.
if (!svg) {
svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="236" height="120" viewBox="0 0 236 120"><rect x="14" y="23" width="200" height="50" fill="#55FF55" stroke="black" stroke-width="1" /></svg>';
}
const buf = Buffer.from(svg, "utf-8");
if (debug) {console.log(`Converting to ${format} with width ${width} & heigth ${height}`);}
sharp(buf)
.resize(width,height)
.toFormat(format, options)
.toBuffer((err, data, info) => {
if(err) {
if (debug) {console.log("Error code");}
res.setHeader("Content-Type", "text/plain");
res.writeHead(500);
res.end(err);
} else {
if (debug) {console.log("Success!");}
res.setHeader("Content-Type", "image/png");
res.setHeader("Content-Transfer-Encoding", "binary");
res.writeHead(200);
res.end(data);
}
})
});
console.log(`Img Server launched on http://${host}:${port}`);
app.listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment