Playing around with colors

Let's have some more fun and add a simple effect: greyscale. Let's add a parameter that will indicate to our service that the user wants the image in shades of grey:

app.param("greyscale", (req, res, next, greyscale) => {
if (greyscale != "bw") return next("route");

req.greyscale = true;

return next();
});

Our parameter will only match the bw string. If it matches, it will mark a flag in the request object.

We can now change our image download function to handle this parameter, if defined:

function download_image(req, res) {
fs.access(req.localpath, fs.constants.R_OK , (err) => {
if (err) return res.status(404).end();

let image = sharp(req.localpath);

if (req.width && req.height) {
image.ignoreAspectRatio();
}

if (req.width || req.height) {
image.resize(req.width, req.height);
}

if (req.greyscale) {
image.greyscale();
}

res.setHeader("Content-Type", "image/" +
path.extname(req.image).substr(1));

image.pipe(res);
});
}

Finally, for every one of our four download routes, we need to add another one to enable grey scaling. This means our user can take advantage of our resizing options and can greyscale the image if he prefers:

app.get("/uploads/:width(\d+)x:height(\d+)-:greyscale-:image", download_image);
app.get("/uploads/:width(\d+)x:height(\d+)-:image", download_image);
app.get("/uploads/_x:height(\d+)-:greyscale-:image", download_image);
app.get("/uploads/_x:height(\d+)-:image", download_image);
app.get("/uploads/:width(\d+)x_-:greyscale-:image", download_image);
app.get("/uploads/:width(\d+)x_-:image", download_image);
app.get("/uploads/:greyscale-:image", download_image);
app.get("/uploads/:image", download_image);

For every one of our initial four routes, we added a similar route before that, with the greyscale parameter. The user just has to prefix the image name with bw- to automatically enable greyscale.

In the end, excluding our first generated thumbnail, you should have something similar to the following code. I removed the code blocks inside the routes and our download function, so you're able to see the base structure:

const bodyparser = require("body-parser");
const path = require("path");
const fs = require("fs");
const express = require("express");
const sharp = require("sharp");
const app = express();

app.param("image", (req, res, next, image) => { ... });
app.param("width", (req, res, next, width) => { ... });
app.param("height", (req, res, next, height) => { ... });
app.param("greyscale", (req, res, next, greyscale) => { ... });

app.post("/uploads/:image", bodyparser.raw({ limit: "10mb", type: "image/*" }), (req, res) => { ... });

app.head("/uploads/:image", (req, res) => { ... });

app.get("/uploads/:width(\d+)x:height(\d+)-:greyscale-:image", download_image);
app.get("/uploads/:width(\d+)x:height(\d+)-:image", download_image);
app.get("/uploads/_x:height(\d+)-:greyscale-:image", download_image);
app.get("/uploads/_x:height(\d+)-:image", download_image);
app.get("/uploads/:width(\d+)x_-:greyscale-:image", download_image);
app.get("/uploads/:width(\d+)x_-:image", download_image);
app.get("/uploads/:greyscale-:image", download_image);
app.get("/uploads/:image", download_image);

app.listen(3000, () => {
console.log("ready");
});

function download_image(req, res) {
...
}

You can now restart our service and make some tests. Taking our first image as an example, we can request a greyscale version:

You can still resize the image as we did before, with the optional greyscale filter:

We can take advantage of the sharp module and add some more interesting image manipulations for our service. This way, we can use it in more projects as it evolves to a full-featured image manipulation service.

We can start by adding a blurring option, something that will make the image seem unfocused. We can also do the opposite, and make the image sharper. We can also flip the image horizontally and vertically.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset