rispondendo alla mia domanda, fornisco una soluzione per l'unione di un'immagine arbitraria con un'immagine bianca & nera. ciò che ancora manca è come impostare il canale alfa per un solo colore di una tela.
I separare la domanda in pezzi e rispondere a ciascuno di essi.
Domanda 1: come convertire una tela in scala di grigi, senza l'iterazione ogni pixel?
Risposta: disegnare l'immagine su una tela bianca con metodo di fusione 'luminosità'
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);
}
Domanda 2: Come convertire una tela in scala di grigi in bianco & bianco, senza l'iterazione ogni pixel?
Risposta: due volte colore Dodge metodo di fusione con #FEFEFE colore farà il lavoro
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();
}
Nota: questa funzione presuppone che si desidera aree nere lasciate in bianco e ogni pixel non-nero diventare bianco! quindi un'immagine in scala di grigi che non ha pixel neri diventerà completamente bianca il motivo per cui scelgo questa operazione è che ha funzionato meglio nel mio caso e usando solo due operazioni di fusione significa che è piuttosto veloce - se vuoi che più pixel scuri vengano lasciati neri e più pixel bianchi diventano bianchi è possibile utilizzare il ciclo commentato per scurire l'immagine in anticipo. quindi il pixel scuro diventerà nero e il pixel più luminoso diventerà più scuro. come si aumenta la quantità di pixel nero del usando il colore-Dodge di nuovo fare il resto del lavoro
Domanda 3: Come unire un nero & tela bianca con un'altra tela senza l'iterazione ogni pixel?
Risposta: uso 'moltiplica' metodo di fusione
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;
}
Domanda 4: Come invertire un Black & Bianco tela senza l'iterazione ogni pixel?
Risposta: modalità uso blend 'differenza'
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();
}
ora a 'merge' un canvasimage con un canvasmask si può fare
convertCanvasToGrayscale(canvasmask);
convertGrayscaleCanvasToBlackNWhite(canvasmask);
result = getBlendedImageWithBlackNWhite(canvasimage, canvasmask);
riguardo alle prestazioni: ovviamente quelli metodi di fusione sono molto più veloci di modificare ogni pixel e per ottenere un po 'più veloce è possibile riunire tutte le funzioni insieme in una sola funzione e riciclare solo un tmpcanvas - ma questo è lasciato alla eader ^^
come sidenote: i testato come la dimensione del png risultante è diverso quando si confrontano sopra è risultato getBlendedImageWithBlackNWhite con la stessa immagine ma le aree nere sono fatti trasparente mediante iterazione ogni pixel e impostazione del canale alfa la differenza in dimensioni è quasi nulla e quindi se non hai davvero bisogno della maschera alfa l'informazione che ogni pixel nero è destinato a essere trasparente può essere sufficiente per l'ulteriore elaborazione
nota: si può invertire il significato di bianco e nero utilizzando il Funzione invertCanvas()
se si desidera sapere più del motivo per cui utilizzo le modalità di fusione o il metodo di fusione des funziona davvero si dovrebbe verificare la matematica dietro di loro - imho non siete in grado di sviluppare tali funzioni ya se non sai come funzionano veramente: math behind blend modes canvas composition standard including a bit math
bisogno di un esempio - individuare la differenza: http://jsfiddle.net/C3fp4/1/
Un altro problema con l'iterazione dei pixel è che la lettura dei dati delle immagini su tela potrebbe incorrere nel problema dell'origine incrociata. –