libro - leer el contenido de un archivo en javascript
Mezcla dos imágenes con lienzo html5 (1)
• Si observa la especificación canvas''context2D sobre el modo de fusión predeterminado (''source-over''):
http://dev.w3.org/fxtf/compositing-1/#simplealphacompositing
Verás que la fórmula utilizada es (renombré las variables para mayor claridad):
colorOut = prevColor x prevAlpha + newColor x newAlpha x (1 - prevAlpha)
Y para alfa resultante:
αlphaOut = prevAlpha + newAlpha x (1 - prevAlpha)
Darse cuenta de,
a) inesperadamente, la fórmula no es lineal (debido a: factor newAlpha x (1 - prevAlpha)).
b) un punto tiene valores r, g, b más pequeños y alfa reducido. Entonces cuando lo reutilice, contribuirá con el cuadrado (0.6) == 0.36 a la imagen final. (... completamente contra-intuitivo ...)
• Entonces, ¿qué ocurre con tus sorteos del 60% / 40%?
1) la imagen A se dibuja con alfa = 60%. La fórmula anterior da:
colorOut = color_A * 0.6 ;
alphaOut = 0.6 ;
2) la imagen B se dibuja con alfa = 40%
colorOut = color_A * 0.6 * 0.6 + color_B x 0.4 x (0.4);
alphaOut = 0.6 + 0.4 * 0.4;
Así que la fórmula final es ==>
colorOut = 0.36 * color_A + 0.16 * color_B ;
alphaOut = 0.76 ;
Ves que no es para nada la mezcla 60/40 que esperabas.
• Como arreglar ?
1) Puedes hacerlo a mano usando getImageData / putImageData. Tenga en cuenta el problema de origen cruzado: si sus imágenes no provienen de su dominio, su imageData estará vacío. Para las actuaciones, apuesta a un factor de desaceleración de más de 50 en comparación con el lienzo (= la GPU) que hace el trabajo. ''tiempo real'' (= 60 fps) podría no ser posible según el tamaño de la imagen / poder de cómputo / navegador. Pero tú tienes el control total.
2) Pero si ahora miras el modo compuesto ''ligther'', parece que tenemos a nuestro hombre:
http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators_plus
La fórmula es ahora:
colorOut = prevColor x prevAlpha + newColor x newAlpha
Y para alfa resultante:
αlphaOut = prevAlpha + newAlpha
Usted ve que este es un simple operador ''plus'', perfecto para su requerimiento.
Entonces la solución es:
- guardar ctx.
- establecer el modo compuesto más ligero.
- dibujar la primera imagen al 60% alfa.
- dibuje una segunda imagen con un 40% de alfa.
- restaurar ctx.
Últimas palabras: si quiere verificar que el alfa final es correcto (== 255), use ese tipo de función:
function logAlpha(ctx,x,y) {
var imDt = ctx.getImageData(x,y,1,1).data;
if (!(imDt[0] || imDt[1] || imDt[2])) console.log(''null point. CORS issue ?'');
console.log('' point at ('' +x+ '','' +y+ '') has an alpha of '' + imDt[3] ) ;
}
Necesito dibujar 2 variaciones de la misma imagen una sobre otra, cuyos valores alfa suman 1.
Por ejemplo :
- imageA
tiene un alfa de 0.4
, mientras que imageB
tiene un alpha de 0.6
.
- El resultado deseado es una imagen completamente opaca (alfa de 1.0
para cada píxel), que aparece como una mezcla del 60% de la imagen imageB
y una mezcla del 40% de la imagen imageA
Sin embargo, creo que el lienzo html5 usa de manera predeterminada un modo de combinación que no sea agregar imágenes mezcladas alfa, por lo que dos elementos dibujados con alfas por debajo de 1 no sumarán hasta 1.
Probé todos los modos de composición diferentes, junto con los modos de fusión de Adobe, pero ninguno de ellos tiene el resultado deseado.
Un caso de prueba simple es dibujar un recto magenta dos veces, ambos con alfa de 0.5
. Mi deseo es que los píxeles resultantes sean rgb(255, 0, 255)
. Sin embargo, el resultado es ligeramente transparente.
¿Alguien sabe alguna forma de lograr este resultado?