¿Cuál es la mejor manera de invertir el canal alfa del contenido de un lienzo?
He visto soluciones como esta , en las que puede revisar píxel por píxel y volver a asignar el valor alfa, pero esta es una operación costosa y esperaba que pudiera haber un método más eficaz (o una mejor práctica). , como una forma de usar context.filter o algo similar para hacer esto.
Como ejemplo simplificado, dada esta imagen, donde todos los píxeles tienen los mismos valores de canal RGB (negro) pero diferentes valores de canal alfa:
Me gustaría producir esta imagen donde los canales RGB no cambian:
Tenga en cuenta que hay un rango de valores alfa en las imágenes originales y finales.
Podemos usar globalCompositeOperation para invertir el color con alfa.
Imagen de origen con degradado radial.
Imagen de resultado con alfa invertido.
Comprobación del resultado: dibujo de la imagen del resultado sobre un fondo amarillo
const src_canvas = document.querySelector('canvas#source'); const src_ctx = src_canvas.getContext('2d'); const result_canvas = document.querySelector('canvas#result'); const result_ctx = result_canvas.getContext('2d'); const check_canvas = document.querySelector('canvas#check'); const check_ctx = check_canvas.getContext('2d'); const w = src_canvas.width = result_canvas.width = check_canvas.width = 180; const h = src_canvas.height = result_canvas.height = check_canvas.height = 180; const gradient = src_ctx.createRadialGradient(w/2,h/2,0, w/2,h/2,w/3); gradient.addColorStop(0, 'rgba(0,0,0,1)'); gradient.addColorStop(1, 'rgba(0,0,0,0)'); src_ctx.fillStyle = gradient; src_ctx.fillRect(0,0,w,h); result_ctx.drawImage(src_canvas,0,0); result_ctx.globalCompositeOperation = 'source-out'; result_ctx.fillRect(0,0,w,h); // uses default fillStyle = 'black' check_ctx.fillStyle = 'yellow'; // to check if the figure isn't fully opaque check_ctx.fillRect(0,0,w,h); check_ctx.drawImage(result_canvas,0,0); <canvas id="source"></canvas> <canvas id="result"></canvas> <canvas id="check"></canvas> Funciona solo si el color base del degradado (su imagen transparente) y el color de fillStyle después de aplicar globalCompositeOperation="source-out" es el mismo. Si tiene diferentes colores en su imagen transparente, no funcionaría.
Tengo el negro como color base de la imagen transparente rgba(0,0,0,...) y el color negro como predeterminado para rellenar cuando result_ctx.fillRect(0,0,w,h) . Si, por ejemplo, el color base de la imagen de origen fuera rojo ( 'rgba(255,0,0,...)' ), entonces tuvimos que definirlo explícitamente antes de fillRect() -> result_ctx.fillStyle = 'red' ('rgb(255,0,0)') ;