Node.js: creare thumbnail dinamiche

Possiamo creare thumbnail dinamiche in Node.js con il modulo gm.

Node.js di Gabriele Romanato

Possiamo creare thumbnail dinamiche in Node.js con il modulo gm.

Dobbiamo installare le librerie GraphicsMagick e ImageMagick. Sul server possiamo usare il package manager della nostra distro (i pacchetti sono imagemagick e graphicsmagick), mentre su macOS possiamo usare Homebrew o MacPorts (i nomi dei pacchetti sono gli stessi).

Quindi possiamo installare il modulo gm:


npm install gm --save

Gestiremo solo immagini JPEG e PNG sotto una specifica directory usando gli stream per ottimizzare la performance:


'use strict';

const path = require('path');
const ABSPATH = path.dirname(process.mainModule.filename);
const gm = require('gm');
const fs = require('fs');

const exists = (path) => {
    try {
        return fs.statSync(path).isFile();
    } catch (e) {
        return false;
    }
};

const getFileExtension = (filename) => {
    return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2);
};

class Media {
    constructor(path) {
        this.src = path;
    }

    isValidMedia(src) {
        return /\.(jpe?g|png)$/.test(src);
    }

    isValidBaseDir(src) {
        return /^\/public\/images/.test(src);
    }

    thumb(request, response) {
        let image = ABSPATH +  this.src;

        if(this.isValidBaseDir(this.src) && this.isValidMedia(this.src) && exists(image)) {

            let width = (request.query.w && /^\d+$/.test(request.query.w)) ? request.query.w : '150';
            let height = (request.query.h && /^\d+$/.test(request.query.h)) ? request.query.h : '150';
            let extension = getFileExtension(this.src);
            let mime = (extension === 'jpeg' || extension === 'jpg') ? 'jpeg' : 'png';

            response.type(mime);

            gm(image).resize(width, height).stream().pipe(response);
        } else {
            response.sendStatus(404);
        }    
    }
}

module.exports = Media;

In ExpressJS dobbiamo solo creare una route specifica:


'use strict';

const app = require('express')();
const Media = require('./classes/Media');

app.get('/thumb', (req, res) => {
    if(req.query.src) {
       let image = new Media(req.query.src);
       image.thumb(req, res);
    } else {
        res.sendStatus(403);
    }
});

app.listen(8080);

Ora possiamo usare un URL come http://localhost:8080/thumb/?src=/public/images/image.jpg&w=640&h=480.

Commenti