2014-09-12 42 views
10

Ho un caso d'uso in cui voglio creare (a) un'applicazione Node che (b) esegue manipolazioni di base dell'immagine (ridimensionamento e ritaglio PNG) ma (c) dove non posso avere dipendenze esterne come librerie native , GraphicsMagick, ImageMagick, PhantonJS, Inkscape, ecc.Pure JavaScript image manipulation

Tutto ciò deve essere fatto in puro JavaScript.

Dato quanto semplice sia la manipolazione che voglio fare (solo ridimensionare e ritagliare PNG), ciò non sembra impossibile. Tuttavia, non riesco a trovare una libreria di ritaglio/ridimensionamento che in definitiva non abbia una dipendenza esterna o nativa.

Esiste una libreria JavaScript autenticamente pura per il ritaglio/ridimensionamento? Quanto sarebbe difficile implementare questo in puro JavaScript, se dovessi farlo da solo? E dove dovrei iniziare?

In alternativa, c'è una funzione C adatta per questo che potrei compilare usando emscripten, ad esempio?

+0

https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=JavaScript%20librar y% 20crop% 2Fresize –

+0

@JamesG. tutte cose grandiose se potessi usare un browser headless, come Phantom JS, un'implementazione DOM, come js-dom. Tuttavia, hanno tutti dipendenze esterne (native). –

+0

La gestione dei file PNG in puro Javascript è * possibile * - per un'interpretazione generosamente ampia di "possibile". Javascript può manipolare file binari con eaze; decomprimere e quindi * ri-comprimere i dati grezzi delle immagini non è così facile (questo richiede una versione JS pura di Flate e Deflate), ma comunque all'interno del regno di "fattibile". Tuttavia, non credo che sarà veloce. – usr2564301

risposta

40

OK, ho finito per rotazione mia, che ho rilasciato come pacchetto NPM qui: https://www.npmjs.org/package/jimp

Esempio di utilizzo è:

var Jimp = require("jimp"); 

var lenna = new Jimp("lenna.png", function() { 
    this.crop(100, 100, 300, 200) // crop 
     .resize(220, 220) // resize 
     .write("lenna-small-cropped.png"); // save 
}); 

La svolta era trovare un ridimensionamento a due passaggi bicubic JavaScript Algoritmo: https://github.com/grantgalitz/JS-Image-Resizer

Complimenti a Mike 'Pomax' Kamermans per indicare la giusta direzione da prendere e Grant Galitz per un algoritmo di ridimensionamento sorprendente.

+0

Grazie mille e sono sorpreso che ci sia un piccolo riscontro. Ho dovuto modificarlo un po 'per lavorare direttamente con i buffer e sicuramente è perfetto per le piccole operazioni. Ottimo lavoro! –

+1

@IgorR, grazie. Se si riscontrano miglioramenti, si prega di aprire un problema o effettuare una richiesta di pull: https://github.com/oliver-moran/jimp –

+1

quello che ho fatto è incompleto e funziona solo con jpg, è un'implementazione sporca non abbastanza buona per un tirare, l'ho fatto funzionare solo per i miei scopi. Quando avrò un po 'di tempo proverò a completarlo per png e a migliorare il codice, e quindi a fare una richiesta di pull. Mi chiedo come la maggior parte delle persone possa essere felice con il peso di * Magicks quando è del tutto possibile fare a meno. –

0

Si può provare a confrontare i moduli per le immagini Node.JS manipolazione - https://github.com/ivanoff/images-manipulation-performance

author's results: 
    sharp.js : 9.501 img/sec; done in 10.525585 sec; 
    canvas.js : 8.246 img/sec; done in 12.12766 sec; 
    gm.js : 4.433 img/sec; done in 22.557112 sec; 
    gm-imagemagic.js : 3.654 img/sec; 
    lwip.js : 1.203 img/sec; 
    jimp.js : 0.445 img/sec; 
+0

Non so perché questo è stato downvoted, ma ho trovato il collegamento sopra abbastanza utile. –

0

Esempio di ridimensionare e ritagliare utilizzando pura manipolazione delle immagini javascript con MarvinJ:

var canvas1 = document.getElementById("canvas1"); 
 
var canvas2 = document.getElementById("canvas2"); 
 
var canvas3 = document.getElementById("canvas3"); 
 

 
image = new MarvinImage(); 
 
image.load("https://i.imgur.com/gaW8OeL.jpg", imageLoaded); 
 

 
function imageLoaded(){ 
 
    imageOut = image.clone() 
 
    image.draw(canvas1) \t 
 
    // Crop 
 
    Marvin.crop(image, imageOut, 50, 50, 100, 100); 
 
    imageOut.draw(canvas2); 
 
    // Scale 
 
    Marvin.scale(image, imageOut, 100); 
 
\t imageOut.draw(canvas3); 
 
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script> 
 
<canvas id="canvas1" width="200" height="200"></canvas> 
 
<canvas id="canvas2" width="200" height="200"></canvas><br/> 
 
<canvas id="canvas3" width="200" height="200"></canvas>