Using Express

As we've seen before, Express gives us a very simple but very useful layer on top of the default Node.js HTTP module. Let's create an empty folder, initialize our package.json file, and install Express:

To help us get around images, we'll use the sharp module, a very fast image manipulation tool for the modern web. It will allow us to easily transform and resize images in a simple serial interface. Let's just install it now:

Let's start by exposing an address to return thumbnails. We'll need to first define our default parameters. Later on, we'll allow the user to change the default values. Our service will run on port 3000 and will accept thumbnail requests on both PNG and JPEG formats. Here's our not-so-simple service:

const express = require("express");
const sharp = require("sharp");
const app = express();

app.get(//thumbnail.(jpg|png)/, (req, res, next) => {
let format = (req.params[0] == "png" ? "png" : "jpeg");
let width = 300;
let height = 200;
let border = 5;
let bgcolor = "#fcfcfc";
let fgcolor = "#ddd";
let textcolor = "#aaa";
let textsize = 24;
let image = sharp({
create : {
width : width,
height : height,
channels : 4,
background : { r: 0, g: 0, b: 0 },
}
});

const thumbnail = new Buffer(
`<svg width="${width}" height="${height}">
<rect
x="0" y="0"
width="${width}" height="${height}"
fill="${fgcolor}" />
<rect
x="${border}" y="${border}"
width="${width - border * 2}" height="${height - border * 2}"
fill="${bgcolor}" />
<line
x1="${border * 2}" y1="${border * 2}"
x2="${width - border * 2}" y2="${height - border * 2}"
stroke-width="${border}" stroke="${fgcolor}" />
<line
x1="${width - border * 2}" y1="${border * 2}"
x2="${border * 2}" y2="${height - border * 2}"
stroke-width="${border}" stroke="${fgcolor}" />
<rect
x="${border}" y="${(height - textsize) / 2}"
width="${width - border * 2}" height="${textsize}"
fill="${bgcolor}" />
<text
x="${width / 2}" y="${height / 2}" dy="8"
font-family="Helvetica" font-size="${textsize}"
fill="${textcolor}" text-anchor="middle">${width} x ${height}</text>
</svg>`
);

image.overlayWith(thumbnail)[format]().pipe(res);
});

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

We start by getting access to both express and sharp modules. We then initialize our Express application:

const express = require("express");
const sharp = require("sharp");
const app = express();

We then create a route to get an image, with a regular expression that will catch the address /thumbnail.png and /thumbnail.jpg. We'll use the extension to ascertain what image type the user wants. We define some default parameters, such as sizes and colors:

let format    = (req.params[0] == "png" ? "png" : "jpeg");
let width = 300;
let height = 200;
let border = 5;
let bgcolor = "#fcfcfc";
let fgcolor = "#ddd";
let textcolor = "#aaa";
let textsize = 24;

We then create an empty image using sharp:

let image = sharp({
create : {
width : width,
height : height,
channels : 4,
background : { r: 0, g: 0, b: 0 },
}
});

We then create an SVG file with an outer border, two crossing lines, and a text in the middle with the size of the image. Next, we overlay the SVG on our empty image, and output the result to the user:

image.overlayWith(thumbnail)[format]().pipe(res);

Finally, we initialize our service on port 3000:

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

Save the full code shown previously as imagini.js, and run it on the console:

You can now head to your web browser and just type the address of our service, and you'll see something like the following image:

We can now start accepting some changes. Let's change our default variables to something like this:

let width     = +req.query.width || 300;
let height = +req.query.height || 200;
let border = +req.query.border || 5;
let bgcolor = req.query.bgcolor || "#fcfcfc";
let fgcolor = req.query.fgcolor || "#ddd";
let textcolor = req.query.textcolor || "#aaa";
let textsize = +req.query.textsize || 24;
The preceding code is not safe for production. Use it only for demonstration purposes. We'll take a look at security in the next chapter.

Restart our service and play with query parameters to see the result. Here's an example of changing the width to 500 px, the border to 2 px, and the foreground color to cyan:

Well, it looks awesome, but it's not very useful as it is, as it just shows the same empty image. Though perhaps more applicable for prototyping, in the real world, it would be more useful if it could create thumbnails from images we upload. Let's do that.

To do so, we need to be able to:

  • Upload images, which should be stored somewhere
  • Check whether an image exists
  • Download an image thumbnail

To simplify, we'll create dynamic routes in a specific path, and we'll use HTTP verbs (GET, POST, DELETE, and so on) to distinguish the actions. When uploading images, we'll use POST and the body should have the image data. To check if an image exists, we'll use HEAD. To download an image thumbnail, we'll use GET.

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

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