2014-09-12 18 views
10

Mam przypadek użycia, w którym chcę utworzyć (a) aplikację węzła, która (b) wykonuje podstawowe operacje na obrazie (zmiana rozmiaru i przycinanie PNG), ale (c) gdzie nie mogę mieć zewnętrznych zależności, takich jak biblioteki natywne , GraphicsMagick, ImageMagick, PhantonJS, Inkscape itp.Czysta manipulacja obrazem JavaScript

Wszystko to musi być wykonane w czystym JavaScript.

Biorąc pod uwagę, jak prosta jest manipulacja, którą chcę zrobić (zmiana rozmiaru PNG i przycięcie) nie wydaje się to niemożliwe. Jednak nie mogę znaleźć biblioteki przycinania/zmiany rozmiaru, która ostatecznie nie będzie miała zależności zewnętrznej lub natywnej.

Czy istnieje prawdziwie czysta biblioteka JavaScript do przycinania/zmiany rozmiaru? Jak trudno byłoby zaimplementować to w czystym JavaScript, gdybym musiał to zrobić sam? I gdzie powinienem zacząć?

Czy istnieje odpowiednia funkcja C do tego, że mogę skompilować przy użyciu emscripten, na przykład?

+0

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

+0

@JamesG. wszystkie świetne rzeczy, gdybym mógł użyć przeglądarki bezgłowej, takiej jak Phantom JS, implementacja DOM, na przykład js-dom. Wszystkie mają jednak zewnętrzne (natywne) zależności. –

+0

Obsługa PNG w czystej wersji Javascript jest * możliwa * - w celu uzyskania hojnej interpretacji "możliwych". JavaScript może manipulować plikami binarnymi za pomocą ezoterycznego; dekompresowanie, a następnie * ponowne * kompresowanie danych obrazu surowego nie jest takie proste (wymaga to czystej wersji JS Flate i Deflate), ale wciąż w zakresie "do wykonania". Jednak nie wierzę, że będzie szybko. – usr2564301

Odpowiedz

40

OK, skończyło się toczenia moje własne, które zostały wydane w postaci pakietu NPM tutaj: https://www.npmjs.org/package/jimp

Przykład użycia:

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 
}); 

Przełomem było znalezienie Bicubic JavaScript dwuprzebiegowego skalowanie Algorytm tutaj: https://github.com/grantgalitz/JS-Image-Resizer

Kudos do Mike'a "Pomax" Kamermans za wskazanie właściwego kierunku i Grant Galitz za niesamowity algorytm skalowania.

+0

Dziękuję i jestem zaskoczony, że istnieje niewielka opinia na ten temat. Musiałem go trochę zmodyfikować, aby pracować bezpośrednio z buforami i zdecydowanie wygląda świetnie na małe operacje. Dobra robota! –

+1

@IgorR, dzięki. Jeśli masz jakieś ulepszenia, proszę otworzyć problem lub złożyć żądanie ściągnięcia: https://github.com/oliver-moran/jimp –

+1

to, co zrobiłem, jest niekompletne i działa tylko z jpg, jest to brudna implementacja, niewystarczająca dla ciągnąć, po prostu sprawiło, że zadziałało dla moich celów. Kiedy będę miał trochę czasu, spróbuję skompletować go dla png i ulepszyć kod, a następnie wykonać żądanie ściągnięcia. Po prostu zastanawiam się, jak większość ludzi może być zadowolona z brzemienia * Magików, kiedy jest to całkowicie możliwe. –

0

Można spróbować porównać node.js moduły dla obrazów manipulacji - 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

Nie wiem, dlaczego to zostało odrzucone, ale uznałem powyższy link za całkiem przydatny. –

0

przykładzie rozmiaru i upraw przy użyciu czystego javascript manipulacji obrazu z 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>