Estoy desarrollando una aplicación web en Node.js (+ express 4) donde los usuarios pueden configurar su imagen de perfil subiéndola al servidor. Ya limitamos el tipo de archivo mime y max, por lo que el usuario no puede cargar más de 200 KB de imágenes png o jpeg.
El problema es que nos gustaría cambiar el tamaño (en el servidor) de la resolución de la imagen cargada a 200x200 para mejorar la carga de la página y ahorrar espacio en el disco. Después de investigar un poco, todas las respuestas apuntaban al uso de cualquier módulo basado en ImageMagick o GraphicsMagick.
Sin embargo, tener que instalar ImageMagick / GraphicsMagick para hacer un simple cambio de tamaño de imagen me parece demasiado exagerado, entonces, ¿hay alguna otra solución que no sea esta para Node.js?
Editar: he cambiado la solución aceptada a aguda ya que la solución anterior (lwip) ya no se mantiene. ¡Gracias por todos tus comentarios!
fuente
Respuestas:
Yo votaría por sharp :
sharp('input.jpg') .resize(200, 200) .toFile('ouput.jpg', function(err) { // output.jpg is a 200 pixels wide and 200 pixels high image // containing a scaled and cropped version of input.jpg });
Es rápido, normalmente 6 veces más rápido que los enlaces de nodo basados en imagemagick más rápidos , y se ejecuta en muy poca memoria, quizás 10 veces menos . enlaces directos a la biblioteca de imágenes libvips directamente, no hay que pagar a un programa externo, y la biblioteca en sí es más rápida y eficiente que * magick en esta tarea. Admite elementos útiles como entrada y salida de flujo, búfer y sistema de archivos, gestión del color, transparencia, promesas, superposiciones, WebP, SVG y más.
A partir de 0,20 npm, npm descargará automáticamente los binarios completos precompilados en la mayoría de las plataformas, por lo que no hay necesidad de node-gyp. Solo ingrese:
o:
Y te vas.
fuente
sharp
ya no tiene dependencias de tiempo de ejecución externas para usuarios de Linux y Windows, ya que incluye una versión precompilada de libvips. Encontrará que las operaciones de cambio de tamaño son ~ 10 veces más rápidas que LWIP y con una fracción del uso de memoria.npm install --global --production windows-build-tools
primero. Ver también github.com/Microsoft/nodejs-guidelines/blob/master/…Recientemente comencé a desarrollar un módulo de procesamiento de imágenes para NodeJS sin dependencias de tiempo de ejecución ( lea por qué ). Todavía está en las primeras etapas, pero ya se puede usar.
Lo que solicita se haría de la siguiente manera:
image.resize(200, 200, function(err, image){ // encode resized image to jpeg and get a Buffer object image.toBuffer('jpg', function(err, buffer){ // save buffer to disk / send over network / etc. }); });
Más información en el repositorio de Github del módulo .
fuente
writeFile
una1.8Mb
imagen y requiere 130 Mb de memoria. Después de eso, hago una prueba4MB, 11000x6000
cambiando el tamaño de una imagen a varias miniaturas (640,560,480, ..., 160) y toma aproximadamente 1.7GB de memoria. ¿Eso es un error?Eche un vistazo a lwip: https://github.com/EyalAr/lwip
Muy simple y facil de usar
y luego en su código de nodo,
// obtain an image object: require('lwip').open('image.jpg', function(err, image){ // check err... // define a batch of manipulations and save to disk as JPEG: image.batch() .scale(0.75) // scale to 75% .rotate(45, 'white') // rotate 45degs clockwise (white fill) .crop(200) // crop a 200X200 square from center .blur(5) // Gaussian blur with SD=5 .writeFile('output.jpg', function(err){ // check err... // done. }); });
He implementado con éxito esto en mi cargador de archivos y funciona como un encanto.
fuente
Hay una buena biblioteca de manipulación de imágenes escrita completamente en JavaScript, sin dependencias de ninguna otra biblioteca, Jimp. https://github.com/oliver-moran/jimp
Uso de ejemplo:
var Jimp = require("jimp"); // open a file called "lenna.png" Jimp.read("lenna.png", function (err, lenna) { if (err) throw err; lenna.resize(256, 256) // resize .quality(60) // set JPEG quality .write("lena-small.jpg"); // save });
fuente
sharp ha gozado de cierta popularidad recientemente, pero es la misma idea que las fijaciones * Magick.
El cambio de tamaño de la imagen no es nada sencillo. El formato JPEG es particularmente complejo y hay varias formas de escalar gráficos con resultados de calidad variable, pocas de ellas de fácil implementación. Las bibliotecas de procesamiento de imágenes existen para hacer este trabajo, así que si no hay otra razón por la que no pueda instalarlas, hágalo.
fuente
Canvas es 2,3 veces más rápido que ImageMagic.
Puede intentar comparar los módulos de Node.js para la manipulación de imágenes: https://github.com/ivanoff/images-manipulation-performance
author's results: sharp.js : 9.501 img/sec; minFreeMem: 929Mb canvas.js : 8.246 img/sec; minFreeMem: 578Mb gm.js : 4.433 img/sec; minFreeMem: 791Mb gm-imagemagic.js : 3.654 img/sec; minFreeMem: 804Mb lwip.js : 1.203 img/sec; minFreeMem: 54Mb jimp.js : 0.445 img/sec; minFreeMem: 82Mb
fuente
Si no necesita una imagen grande, puede cambiar su tamaño en el lado del cliente antes de cargarla:
Leer archivos en JavaScript usando las API de archivos
Cambio de tamaño de la imagen del lado del cliente con javascript antes de cargarla en el servidor
Muchos usuarios pueden tener una buena imagen de sí mismos desde un teléfono inteligente, y muchos de ellos tienen más de 200kB. Tenga en cuenta que los datos proporcionados por el cliente no son confiables, por lo que aún se aplican las verificaciones del lado del servidor.
fuente
Estaba usando lwip (como sugirió anteriormente arvind) pero cambié a png-crop . Parece funcionar un poco más rápido para mí (Win 8.1 x64, Node v0.12.7). El código en el repositorio parece increíblemente liviano y, desde el punto de vista operativo, es fácil de usar.
var pngcrop = require('png-crop'); var config = {left: 10, top: 100, height: 150, width: 150}; pngcrop.crop('cats.png','cats-cropped.png',config);
Por supuesto, solo hará archivos png ...
fuente
Sharp funciona muy bien y es fácil de usar con streams, funciona a las mil maravillas, pero necesitas compilarlo con la versión de nodo, esto es una desventaja. Estaba usando Sharp para el procesamiento de imágenes, con una imagen de un bucket de AWS S3 y funcionó perfectamente, pero tuve que usar otro módulo. GM no funcionó para mí, ¡pero Jimp funcionó muy bien!
Debes prestar atención a la ruta de la imagen escrita, podría darte algunos errores si comienzas la ruta con una "/".
Así es como usé Jimp en nodeJS:
const imageUrl = `SOME_URL`; let imgExported = 'EXPORTED_PIC.png'; Jimp.read(imageUrl) .then(image => { image .resize(X, Y) .write(`tmp/`+ imgExported, err => { if(err) console.error('Write error: ', err); else { ... // don't forget to put a callback() } } });
También tenga cuidado con el orden de ejecución, devuelva la llamada para que no sucedan otras cosas cuando no lo desee. Intenté usar "await" para Jimp.read () pero no funcionó bien.
fuente
Puedes hacer esto usando jimp (node_module)
Escritura local:
Jimp.read(path) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .write('path-to-save'); }) .catch(err => { console.log(err); });
Para subir a s3 o donde quieras.
Jimp.read(urls) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .getBase64(Jimp.AUTO, (err, res) => { const buf = new Buffer( res.replace(/^data:image\/\w+;base64,/, ""), "base64" ); var data = { Key: key, Bucket: bucket, Body: body, ContentEncoding: "base64", ContentType: "image/jpeg" }; s3.putObject(data, function(err, data) { if (err) { throw err; } else { console.log("succesfully uploaded the image!"); } }); }); }) .catch(err => { console.log(err); });
fuente
Me gusta la biblioteca resize-img por su simplicidad.
const fs = require('fs'); const resizeImg = require('resize-img'); (async () => { const image = fs.readFileSync('unicorn.png'); const newImage = await resizeImg(image, { width: 128, height: 128 }); fs.writeFileSync('unicorn-128x128.png', newImage); })();
fuente
Se implementó el cambio de tamaño de la imagen usando la API de Google Drive v3 . Este método se recomienda para que Google Apps Script inserte imágenes en Google Sheets.
Algoritmo:
Vea el ejemplo aquí: https://github.com/dobromyslov/google-drive-utils/blob/511c44c2c48862b47c60038423b7f71bf1d28f49/src/index.ts#L150
Y cuidado con las cuotas de GDrive:
fuente