Node.js: creare thumbnail dinamiche

Node.js: creare thumbnail dinamiche

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.

Torna su