odpowiadając na moje własne pytanie, zapewniam rozwiązanie do scalania dowolnego obrazu z czarnym białym obrazem &. to, czego wciąż brakuje, to jak ustawić kanał alfa dla tylko jednego koloru płótna.
Rozdzielam pytanie na części i odpowiadam na nie.
Pytanie 1: Jak przekonwertować płótno do skali szarości bez iteracji każdy piksel?
Odpowiedź: narysować obraz na białym płótnie z trybu mieszania „jasności”
function convertCanvasToGrayscale(canvas){
var tmp = document.createElement('canvas');
tmp.width = canvas.width;
tmp.height = canvas.height;
var tmpctx = tmp.getContext('2d');
// conversion
tmpctx.globalCompositeOperation="source-over"; // default composite value
tmpctx.fillStyle="#FFFFFF";
tmpctx.fillRect(0,0,canvas.width,canvas.height);
tmpctx.globalCompositeOperation="luminosity";
tmpctx.drawImage(canvas,0,0);
// write converted back to canvas
ctx = canvas.getContext('2d');
ctx.globalCompositeOperation="source-over";
ctx.drawImage(tmp, 0, 0);
}
Pytanie 2: Jak przekonwertować szarości płótno na czarno & biały bez iteracji każdy piksel?
Odpowiedź: dwa razy kolor Dodge tryb mieszania z kolorowym #FEFEFE wykona pracę
function convertGrayscaleCanvasToBlackNWhite(canvas){
var ctx = canvas.getContext('2d');
// in case the grayscale conversion is to bulky for ya
// darken the canvas bevore further black'nwhite conversion
//for(var i=0;i<3;i++){
// ctx.globalCompositeOperation = 'multiply';
// ctx.drawImage(canvas, 0, 0);
//}
ctx.globalCompositeOperation = 'color-dodge';
ctx.fillStyle = "rgba(253, 253, 253, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.globalCompositeOperation = 'color-dodge';
ctx.fillStyle = "rgba(253, 253, 253, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
}
Uwaga: Funkcja ta zakłada, że chcesz czarne obszary lewy czarny i każdy non-czarny piksel stać się białym! w ten sposób obraz w skali szarości, który nie ma czarnego piksela, stanie się całkowicie biały Powodem, dla którego wybrałem tę operację jest to, że działa lepiej w moim przypadku i użycie tylko dwóch operacji mieszania oznacza, że jest dość szybki - jeśli chcesz, aby więcej ciemnego piksela pozostało czarne i bardziej biały piksel staje się biały, możesz użyć zapętlonej pętli, aby wcześniej przyciemnić obraz. w ten sposób ciemny piksel stanie się czarny, a jaśniejszy piksel stanie się ciemniejszy. jak zwiększyć ilość czarny piksel za pomocą koloru i Dodge'a ponownie wykona resztę zadania
Pytanie 3: Jak scalić Czarny & białym płótnie z innym płótnie bez iteracji każdy piksel?
Odpowiedź: stosowanie 'pomnożyć' tryb mieszania
function getBlendedImageWithBlackNWhite(canvasimage, canvasbw){
var tmp = document.createElement('canvas');
tmp.width = canvasimage.width;
tmp.height = canvasimage.height;
var tmpctx = tmp.getContext('2d');
tmpctx.globalCompositeOperation = 'source-over';
tmpctx.drawImage(canvasimage, 0, 0);
// multiply means, that every white pixel gets replaced by canvasimage pixel
// and every black pixel will be left black
tmpctx.globalCompositeOperation = 'multiply';
tmpctx.drawImage(canvasbw, 0, 0);
return tmp;
}
Pytanie 4: Jak odwrócić Czarny & białego płótna bez iteracji każdy piksel?
Odpowiedź: Tryb stosowanie 'różnica' mieszanka
function invertCanvas(canvas){
var ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = 'difference';
ctx.fillStyle = "rgba(255, 255, 255, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
}
teraz do 'scalenia' na canvasimage z canvasmask można zrobić
convertCanvasToGrayscale(canvasmask);
convertGrayscaleCanvasToBlackNWhite(canvasmask);
result = getBlendedImageWithBlackNWhite(canvasimage, canvasmask);
dotyczących wydajności: Oczywiście te tryby mieszania są znacznie szybsze niż modyfikowanie każdego piksela i aby uzyskać nieco szybszy można spakować wszystkie funkcje razem w razie potrzeby do jednej funkcji i odtworzyć tylko jeden tmpcanvas - ale to pozostało do eader ^^
jak sidenote: i testowano jak wielkość wynikającą png różni jeśli porównać powyżej znajduje getBlendedImageWithBlackNWhite wynik z tego samego obrazu, ale czarne obszary są przejrzyste przez powtarzanie każdy piksel i ustawiania kanału alfa różnicę Rozmiar jest prawie zerowy, a więc jeśli naprawdę nie potrzebujesz maski alfa, informacja, że każdy czarny piksel ma być przezroczysty, może być wystarczająca do dalszego przetwarzania. Uwaga: można odwrócić znaczenie czerni i bieli za pomocą Funkcja invertCanvas()
jeśli chcesz wiedzieć więcej o tym, dlaczego używam tych trybów mieszania lub jak mieszać mo des naprawdę działa należy sprawdzić matematyki za nimi - imho nie jesteś w stanie opracować takie funkcje, jeśli ya nie wiem jak one naprawdę działają: math behind blend modes canvas composition standard including a bit math
potrzebują przykład - dostrzec różnicę: http://jsfiddle.net/C3fp4/1/
Kolejny problem z iteracyjnymi pikselami polega na tym, że odczytanie obrazu na płótnie może napotkać problem z krzyżowym początkiem. –