Trabajar con imágenes en Node.js – GraphicsMagick e ImageMagick

    Introducción

    A medida que las imágenes se han convertido en una parte integral de la web, la necesidad de procesamiento de imágenes se vuelve siempre presente. Hay varias bibliotecas y binarios que se utilizan para el procesamiento de imágenes en Node.js, dos de los cuales son GráficosMagia y ImageMagick.

    ImageMagick es un software de procesamiento de imágenes de código abierto para crear, modificar y convertir imágenes. GraphicsMagick es una herramienta similar que originalmente era una bifurcación del proyecto ImageMagick que se ha convertido en un proyecto independiente con varias mejoras.

    Algunas de las ventajas que GraphicsMagick tiene sobre ImageMagick incluyen más eficiencia, un tamaño más pequeño, menos vulnerabilidades de seguridad y, en general, es más estable que ImageMagick. Ambos están disponibles para su uso en Node.js como paquetes NPM: GraphicsMagick e ImageMagick.

    Instalación de GraphicsMagick e ImageMagick

    Antes de instalar cualquiera de estos paquetes, debe descargar e instalar las herramientas de la interfaz de línea de comandos (CLI) en su sistema. También puede utilizar ImageMagick directamente desde GraphicsMagick.

    Si planea usar el módulo GraphicsMagick, puede instalar las herramientas CLI ImageMagick o GraphicsMagick. Si, en cambio, desea utilizar ImageMagick, debe instalar la herramienta CLI de ImageMagick.

    Después de descargar e instalar la herramienta CLI requerida, puede verificar la versión de su instalación ejecutando los siguientes comandos en su terminal.

    Para ImageMagick:

    $ convert -version
    

    Si se ha instalado correctamente, esto imprimirá los detalles del software instalado en el terminal.

    Para GraphicsMagick:

    Te puede interesar:Escribir en archivos usando el comando cat en Linux
    $ gm convert logo: logo.miff
    $ gm convert logo.miff win:
    

    Del mismo modo, si la instalación se realizó correctamente, se mostrará el logotipo de GraphicsMagick en una ventana.

    A continuación, para agregar el módulo a su proyecto, usaremos npm.

    Para ImageMagick:

    $ npm install imagemagick
    

    Para GraphicsMagick:

    $ npm install gm
    

    Procesamiento de imágenes en Node.js con GraphicsMagick

    En este tutorial, aprenderemos a trabajar con imágenes en Node.js usando GraphicsMagick e ImageMagick. En esta sección, comenzaremos con GraphicsMagick.

    Crea una carpeta llamada node-graphics-magick, cd en la carpeta, inicialice el proyecto Node con la configuración predeterminada e instale GraphicsMagick como se muestra a continuación:

    $ mkdir node-graphics-magick
    $ cd node-graphics-magick
    $ npm init -y
    $ npm install gm
    

    A continuación, abra la carpeta con su editor de código favorito y cree un index.js archivo. Para usar el módulo en el proyecto, impórtelo usando require(). También agregaremos el sistema de archivos nativo (fs) módulo para ayudarnos a interactuar con el sistema de archivos:

    const fs = require('fs');
    const gm = require('gm');
    

    También desea agregar una imagen a su carpeta que se usará en este tutorial, la nombraremos sample_image.

    Como se mencionó anteriormente, el módulo GraphicsMagick también le permite usar ImageMagick. Si desea utilizar esta opción, deberá importar la subclase:

    Te puede interesar:node: Mostrar archivos en un directorio
    const gm = require('gm').subClass({imageMagick: true});
    

    Llamar al constructor gm

    Hay tres formas en las que puede llamar al gm método constructor.

    • Pasando la ruta a la imagen como un argumento de cadena:
    const gm = require('gm');
    
    gm('sample_image');
    
    • También puede pasar un ReadableStream o Buffer como primer argumento, con un nombre de archivo opcional para la inferencia de formato:
    const gm = require('gm');
    
    // ReadableStream
    let readableImageFileStream = fs.createReadStream('sample_image1.jpeg');
    gm(readableImageFileStream, sample_image);
    
    // Buffer
    let imageFileBuffer = fs.readFileSync('sample_image1.jpeg');
    gm(imageFileBuffer);
    
    • Otra opción es pasar dos enteros para width y height con un color de fondo opcional para crear una nueva imagen sobre la marcha:
    const gm = require('gm');
    
    gm(300, 300, "#00ff55aa");
    

    Obtener información de la imagen

    GraphicsMagick proporciona varios captadores para recuperar información sobre imágenes. Uno es el identify() método. Devuelve todos los datos de imagen disponibles:

    const gm = require('gm');
    
    gm("sample_image.jpg").identify(function(err, value) {
        console.log(value);
    
        if(err) {
            console.log(err);
        }
    });
    

    Después de incluir el gm módulo, llamamos al gm() constructor y luego llamó al identify() función pasando una función que toma dos argumentos – err para obtener cualquier error que ocurra y value que contiene la información de la imagen.

    Estamos imprimiendo el value a nuestra consola y verificando si hay algún error. Si ocurrió un error, se registrará en la consola. Puede usar ese bloque para detectar errores y mostrar mensajes apropiados en situaciones de la vida real.

    Tenga en cuenta que el valor podría ser undefined.

    La ejecución de este código devolverá un objeto con todos los datos de imagen disponibles para la imagen. Así es como se ve la salida para una imagen que usamos:

    {
      Format: 'JPEG (Joint Photographic Experts Group JFIF format)',
      format: 'JPEG',
      Geometry: '213x133',
      size: { width: 213, height: 133 },
      Class: 'DirectClass',
      Type: 'true color',
      Depth: '8 bits-per-pixel component',
      ...
      Signature: 'ae5b5e492457ac667e9a4cb1e7b78b7e6459fbf342ea741857ee4e9e1092ad73',
      Tainted: 'False',
      path: 'sample_image.jpg'
    }
    

    Proporciona información sobre el size, resolution, file size y color de la imagen depth Entre otros. Si desea obtener algunos de estos detalles individualmente, hay una función separada para obtenerlos, como: size(), format(), depth(), orientation(), res()etc.

    Todos tienen la misma sintaxis que el identify() función. Por ejemplo, si quisiéramos recuperar el tamaño de una imagen, usaríamos:

    const gm = require('gm');
    
    gm("sample_image.png").size(function(err, value) {
        console.log(value);
        if(err) {
            console.log(err);
        }
    });
    

    Cambiar el tamaño de las imágenes

    También es común cambiar el tamaño de las imágenes. La sintaxis de resize() funciones es:

    Te puede interesar:El mito de la multitarea como desarrollador
    resize(width, [, height [, options]])
    

    Donde el height y options los parámetros son opcionales. los options el parámetro puede ser %, @, !, < o >. Cubriremos cada uno de estos.

    los width y height especificados son los valores máximos permitidos para ambas propiedades.

    Sin especificar ninguna options, GraphicsMagick mantendrá la relación de aspecto de la imagen original. Si ambos width y height se dan, la imagen se redimensionará hasta que alcance el valor máximo para uno u otro.

    Sin embargo, puede forzar que el módulo cambie de tamaño al width y height usando el ! opción.

    También usamos el write() función para guardar la salida en un nuevo archivo.

    Cambiar el tamaño de una imagen a una width manteniendo la relación de aspecto:

    const gm = require('gm');
    
    gm("sample_image.jpg")
        .resize(200)
        .write('resized_img_width_only.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
    

    También podemos cambiar el tamaño de una imagen hasta que alcance el máximo width o height manteniendo la ración de aspecto:

    const gm = require('gm');
    
    gm("sample_image.jpg")
        .resize(200, 200)
        .write('resized_img_widthandheight.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        })
    

    O podemos cambiar el tamaño de una imagen para que se ajuste al width y height, posiblemente cambiando la relación de aspecto original:

    const gm = require('gm');
    
    gm("sample_image.jpg")
        .resize(600, 200, '!')
        .write('resized_to_fit.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
    

    También podemos usar porcentajes en lugar de píxeles para cambiar el tamaño de las imágenes, es decir, podemos cambiar el tamaño de la imagen al 50% de su tamaño original:

    Te puede interesar:Preparación para una entrevista de trabajo como programador
    const gm = require('gm');
    
    gm("img.png")
        .resize(50, 50, "%")
        .write('resized_img_percentage.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
    

    Por supuesto, también puede dar un porcentaje superior al 100% para agrandar la imagen.

    Otra opción interesante que puedes utilizar es @, que cambia el tamaño de la imagen de tal manera que ocupa como máximo width*height píxeles. Esto significa que si escribe algo como esto:

    const gm = require('gm');
    
    gm("sample_image.jpg")
        .resize(100, 100, "@")
        .write('resized_img_max_area_in_pixels.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
    

    Se cambiará el tamaño de la imagen para que se ajuste a un área de 10.000 píxeles (100 * 100 = 10.000 píxeles). En otras palabras, si multiplicamos el ancho y el alto de la imagen resultante, será un número menor o igual a 10.000.

    Ahora tomaremos en el > y < opciones:

    • los > La opción cambia el tamaño de una imagen solo si el ancho y el alto de la imagen dada son mayor que el dado width y height.
    • los < La opción cambia el tamaño de una imagen solo si el ancho y el alto de la imagen dada son menor que el dado width y height.
    const gm = require('gm');
    
    // Resize image if image width is greater than 100 and image height is greater than 100
    gm("sample_image.jpg")
        .resize(100, 100, ">")
        .write('resized_img_greater_than_100x100.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
        
    // Resize image if image width is less than 100 and image height is less than 100
    gm("sample_image.jpg")
        .resize(100, 100, "<")
        .write('resized_img_less_than_100x100.jpg', function (err) {
            if(err) console.log(err);
            console.log("Done!")
        });
    

    Conversión de imágenes de un formato a otro

    Otra cosa común que nos gustaría hacer con las imágenes es convertir una imagen de un formato a otro. Esto se puede hacer de una manera muy sencilla, simplemente cambiando la extensión del archivo a uno de los formatos compatibles:

    const gm = require('gm');
    
    gm("sample_image.jpg")
        .write('sample_image.png', function(err) {
            if(err) console.log(err);
            console.log("Jpg to png!")
        });
    

    Recortar imágenes

    Además de cambiar el tamaño de las imágenes, es posible que también desee recortar imágenes en su aplicación. GraphicsMagick tiene un crop() función y su sintaxis es:

    gm("sample_image.png").crop(width, height, [x, y[, percentage]])
    

    Donde los parámetros tienen el siguiente significado:

    • width y height son las dimensiones a las que desea recortar la imagen. Estos se tratan como números de píxeles o como porcentajes de la imagen original según la percentage parámetro.
    • x y y son parámetros opcionales y representan las coordenadas de la posición desde donde debe comenzar el recorte. El valor predeterminado es 0 para ambos, lo que significa que el recorte comienza desde la esquina superior izquierda de la imagen.
    • los percentage El parámetro también es opcional y se utiliza para especificar si los valores de la width y height representan porcentajes de las dimensiones o píxeles de la imagen. los percentage opción por defecto es false.
    const gm = require('gm');
    
    // Crop image to 100x100 at position 20, 20
    gm("sample_image.jpg")
        .crop(100, 100, 20, 20)
        .write('resized_img_crop.jpg', function (err, value) {
            if(err) console.log(err);
            console.log(value);
        });
        
    
    // Crop image to 50% if both width and height at position 10, 10 
    gm("sample_image.jpg")
        .crop(50, 50, 10, 10, true)
        .write('resized_img_crop1.jpg', function (err, value) {
            if(err) console.log(err);
            console.log(value);
        });
    

    Nuevamente, si verifica las dimensiones de la nueva imagen resized_img_crop1, puede ver que tiene la mitad del tamaño de la imagen original y está recortada en una posición particular en lugar de desde la esquina superior izquierda.

    La siguiente imagen muestra un ejemplo:

    Te puede interesar:Uso de Sequelize.js y SQLite en una aplicación Express.js

    Hemos echado un vistazo a cómo realizar la manipulación de imágenes con GraphicsMagick. A continuación, veremos cómo hacerlo en ImageMagick.

    Procesamiento de imágenes en Node.js con ImageMagick

    El módulo ImageMagick no se ha mantenido durante algún tiempo y los desarrolladores incluso aconsejan usar el módulo GraphicsMagick en su lugar. Sin embargo, para este tutorial, también veremos brevemente algunas de las funciones principales de este módulo.

    Crea una carpeta llamada node-image-magick siguiendo los pasos de la sección anterior, instale el módulo ImageMagick a través de npm y crea un index.js archivo.

    En el index.js archivo, agregue el módulo usando require():

    const im = require('image-magick');
    

    Obtener información de la imagen

    Para obtener información de la imagen, hay una identify() método en el image-magick módulo también. El primer argumento es la ruta a la imagen y el segundo es una función de devolución de llamada que tiene dos argumentos: err para manejar errores y info para recuperar la información de la imagen:

    const im = require('image-magick');
    
    im.identify('sample_image.jpg', function (err, info) {
        if(err) console.log(err);
        console.log(info);
    });
    

    Ejecutando este código para nuestra imagen se imprime:

    {
      format: 'JPEG',
      'mime type': 'image/jpeg',
      class: 'DirectClass',
      geometry: '213x133+0+0',
      units: 'Undefined',
      colorspace: 'sRGB',
      type: 'TrueColor',
      'base type': 'Undefined',
      endianess: 'Undefined',
      depth: 8,
      'channel depth': { red: '8-bit', green: '8-bit', blue: '8-bit' },
      ...
      width: 213,
      height: 133
    }
    

    Cambiar el tamaño de las imágenes

    ImageMagick proporciona una función conveniente para cambiar el tamaño de las imágenes que incluye un objeto con opciones para cambiar el tamaño de la imagen y una función de devolución de llamada. El cambio de tamaño de las imágenes mediante el módulo ImageMagick sigue la siguiente sintaxis:

    const im = require('image-magick');
    
    im.resize({
        srcPath: 'sample_image.jpg',
        dstPath: 'sample_image_resized.jpg',
        width:   256
      }, function(err, stdout, stderr){
           if (err) throw err;
           console.log('resized');
    });
    

    Recortar imágenes

    ImageMagick también proporciona una función para recortar imágenes con la misma sintaxis que resize() función. Echemos un vistazo a un ejemplo de uso simple:

    const im = require('image-magick');
    
    im.crop({
        srcPath: 'sample_image.jpg',
        dstPath: 'sample_image_cropped.jpg',
        width: 800,
        height: 600,
        quality: 1,
        gravity: "North"
      }, function(err, stdout, stderr){
           if(err) console.log(err);
    });
    

    La documentación proporciona una lista de las opciones para cada una de las funciones anteriores.

    Te puede interesar:Ejemplo: cargar un archivo en AWS S3 con Boto

    Conclusión

    En este artículo exploramos cómo trabajar con imágenes en Node.js usando los módulos ImageMagick y GraphicsMagick. GraphicsMagick es la mejor opción de las dos, dadas todas las ventajas que tiene sobre ImageMagick.

    El módulo GraphicsMagick tiene una amplia documentación sobre más opciones para manipular imágenes.

     

    Rate this post

    Etiquetas: