Ich entwickle eine Web-App auf Node.js (+ Express 4), in der Benutzer ihr Profilbild festlegen können, indem sie es auf den Server hochladen. Wir beschränken bereits den Dateimimetyp und die maximale Dateigröße, sodass der Benutzer nicht mehr als 200 KB PNG- oder JPEG-Bilder hochladen kann.
Das Problem ist, dass wir die Größe der hochgeladenen Bilder auf 200 x 200 ändern möchten, um das Laden von Seiten zu verbessern und Speicherplatz auf der Festplatte zu sparen. Nach einigen Recherchen deuteten alle Antworten auf die Verwendung eines Moduls hin, das auf ImageMagick oder GraphicsMagick basiert.
Die Installation von ImageMagick / GraphicsMagick für eine einfache Größenänderung von Bildern scheint mir jedoch zu übertrieben. Gibt es für Node.js eine andere Lösung als diese?
Bearbeiten: Ich habe die akzeptierte Lösung in scharf geändert, da die vorherige Lösung (lwip) nicht mehr beibehalten wird. Vielen Dank für Ihr Feedback!
quelle
Antworten:
Ich würde für scharf stimmen :
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 ist schnell, normalerweise 6x schneller als die schnellsten Imagemagick-basierten Knotenbindungen und läuft in sehr wenig Speicher, vielleicht 10x weniger . scharfe Links zur libvips-Bildbibliothek direkt, es gibt kein Shelling zu einem externen Programm, und die Bibliothek selbst ist bei dieser Aufgabe schneller und effizienter als * magick. Es unterstützt nützliche Dinge wie die Eingabe und Ausgabe von Streams, Puffern und Dateisystemen, Farbmanagement, Transparenz, Versprechen, Überlagerungen, WebP, SVG und mehr.
Ab Punkt 0.20 lädt npm auf den meisten Plattformen automatisch vollständige vorkompilierte Binärdateien herunter, sodass Node-Gyp nicht erforderlich ist. Geben Sie einfach ein:
oder:
Und los geht's.
quelle
sharp
gibt es keine externen Laufzeitabhängigkeiten mehr für Linux- und Windows-Benutzer, da eine vorkompilierte Version von libvips gebündelt wird. Sie werden feststellen, dass Größenänderungsvorgänge ~ 10x schneller als LWIP und zu einem Bruchteil der Speichernutzung sind.npm install --global --production windows-build-tools
zuerst. Siehe auch github.com/Microsoft/nodejs-guidelines/blob/master/…Ich habe vor kurzem begonnen, ein Bildverarbeitungsmodul für NodeJS ohne Laufzeitabhängigkeiten zu entwickeln ( lesen Sie warum ). Es ist noch in einem frühen Stadium, aber bereits verwendbar.
Was Sie verlangen, würde wie folgt geschehen:
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. }); });
Weitere Infos im Github-Repo des Moduls .
quelle
writeFile
ein1.8Mb
Bild zu erstellen, und es benötigt 130 MB Speicher. Danach mache ich einen Test, indem ich die4MB, 11000x6000
Größe eines Bildes auf mehrere Miniaturansichten (640.560.480, ..., 160) ändere. Es benötigt ungefähr 1,7 GB Speicher. Ist das ein Fehler?Schauen Sie sich lwip an: https://github.com/EyalAr/lwip
Sehr einfach und leicht zu bedienen
und dann in Ihrem Knotencode,
// 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. }); });
Ich habe dies erfolgreich in meinem Datei-Uploader implementiert und es funktioniert wie ein Zauber.
quelle
Es gibt eine gute Bildbearbeitungsbibliothek, die vollständig in JavaScript geschrieben ist, ohne Abhängigkeiten zu anderen Bibliotheken, Jimp. https://github.com/oliver-moran/jimp
Anwendungsbeispiel:
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 });
quelle
scharf hat in letzter Zeit einige Popularität genossen, aber es ist die gleiche Idee wie * Magick-Bindungen.
Die Größenänderung von Bildern ist alles andere als einfach. Das JPEG-Format ist besonders komplex und es gibt verschiedene Möglichkeiten, Grafiken mit Ergebnissen unterschiedlicher Qualität zu skalieren, von denen nur wenige einfach zu implementieren sind. Für diesen Job gibt es Bildverarbeitungsbibliotheken. Wenn es also keinen anderen Grund gibt, warum Sie sie nicht installieren können, versuchen Sie es.
quelle
Canvas ist 2,3-mal schneller als ImageMagic.
Sie können versuchen, Node.js-Module für die Bildbearbeitung zu vergleichen - 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
quelle
Wenn Sie kein großes Bild benötigen, können Sie die Größe auf der Clientseite ändern, bevor Sie es hochladen:
Lesen von Dateien in JavaScript mithilfe der Datei-APIs
Ändern der Bildgröße auf der Clientseite mit Javascript vor dem Hochladen auf den Server
Viele Benutzer haben möglicherweise ein gutes Bild von sich selbst von einem Smartphone, und viele von ihnen sind über 200 KB groß. Beachten Sie, dass vom Client bereitgestellte Daten nicht vertrauenswürdig sind, sodass weiterhin serverseitige Überprüfungen gelten.
quelle
Ich habe lwip verwendet (wie zuvor von arvind vorgeschlagen), aber auf png-crop umgestellt . Es scheint für mich etwas schneller zu funktionieren (Win 8.1 x64, Node v0.12.7). Der Code im Repo sieht unglaublich leicht aus und ist betrieblich einfach zu bedienen.
var pngcrop = require('png-crop'); var config = {left: 10, top: 100, height: 150, width: 150}; pngcrop.crop('cats.png','cats-cropped.png',config);
Natürlich werden nur PNG-Dateien ausgeführt ...
quelle
Sharp funktioniert sehr gut und ist einfach mit Streams zu verwenden, funktioniert wie ein Zauber, aber Sie müssen es mit der Knotenversion kompilieren, dies ist ein Nachteil. Ich habe Sharp für die Bildverarbeitung mit einem Bild aus einem AWS S3-Bucket verwendet und habe einwandfrei funktioniert, musste aber ein anderes Modul verwenden. GM hat nicht für mich gearbeitet, aber Jimp hat sehr gut gearbeitet!
Sie müssen auf den Pfad des geschriebenen Bildes achten. Wenn Sie den Pfad mit einem "/" beginnen, kann dies zu Fehlern führen.
So habe ich Jimp in nodeJS verwendet:
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() } } });
Achten Sie auch auf die Reihenfolge der Ausführung und rufen Sie zurück, damit andere Dinge nicht passieren, wenn Sie nicht möchten. Ich habe versucht, "warte" für Jimp.read () zu verwenden, aber es hat den Job nicht gut gemacht.
quelle
Sie können dies mit jimp (node_module) tun.
Lokales Schreiben:
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); });
Zum Hochladen auf s3 oder wo immer Sie möchten.
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); });
quelle
Ich mag resize-img Bibliothek für seine Einfachheit.
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); })();
quelle
Implementierte Größenänderung von Bildern mithilfe der Google Drive API v3 . Diese Methode wird für Google Apps Script empfohlen, um Bilder in Google Sheets einzufügen.
Algorythm:
Siehe Beispiel hier: https://github.com/dobromyslov/google-drive-utils/blob/511c44c2c48862b47c60038423b7f71bf1d28f49/src/index.ts#L150
Und Vorsicht vor GDrive-Quoten:
quelle