Estoy tratando de crear un filtro para lienzo que dibuje una versión monocromática de una imagen. Estoy dibujando la imagen, luego itero a través de los datos de la imagen, luego cambio esos valores rgb a un gris, luego coloco los datos de la imagen en el lienzo. Necesito ayuda sobre cómo crear el tono gris a partir de los valores rgb. Quiero una solución javascript.
Mi código:
function toGray(vals) { var r = vals[0] var g = vals[1] var b = vals[2] // Return gray shade } function filter() { var c = document.getElementById("canvas1"); var ctx = c.getContext("2d"); var img = document.createElement('img') img.src = 'shaq.png' img.onload = function() { ctx.drawImage(img, 0, 0, c.width, c.height); var imgData = ctx.getImageData(0, 0, c.width, c.height); var i; for (i = 0; i < imgData.data.length; i += 4) { var rgblist = [imgData.data[i], imgData.data[i+1], imgData.data[i+2]] var filtered = toGray(rgblist) imgData.data[i] = filtered[0] imgData.data[i+1] = filtered[1] imgData.data[i+2] = filtered[2] } ctx.putImageData(imgData, 0, 0); } } canvas { position: absolute; bottom: 10px; left: 0; width: 100vw; height: 100vh; } <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>filter</title> <link href="style.css" rel="stylesheet" type="text/css" /> </head> <body> <canvas id="canvas1"></canvas> <script src="codes.js"></script> <script src="filter.js"></script> <script src="script.js"></script> </body> </html>Simplemente encuentre el promedio de los valores rgb, luego insértelo como los valores rojo, verde y azul para crear gris.
Su nueva función toGray sería:
function toGray(vals) { var r = vals[0] var g = vals[1] var b = vals[2] return (r+g+b)/3 }Hay tres algoritmos para convertir color a escala de grises básicamente.
ligereza, promedio, método de luminosidad
El método de la luminosidad promedia los colores más prominentes y menos prominentes:
(max(R, G, B) + min(R, G, B)) / 2
El método promedio simplemente promedia los valores: (R + G + B) / 3
El método de la luminosidad es una versión más sofisticada del método promedio. También promedia los valores, pero forma un promedio ponderado para tener en cuenta la percepción humana. Somos más sensibles al verde que a otros colores, por lo que el verde tiene una mayor ponderación. La fórmula de la luminosidad es 0.21 R + 0.72 G + 0.07 B
De acuerdo con la fórmula de cálculo anterior, la función será:
function toGray(vals) { var r = vals[0]; var g = vals[1]; var b = vals[2]; return Math.round((Math.min(r, g, b) + Math.max(r, g, b)) / 2); // return Math.round((r + g + b) / 3); // return Math.round(0.21 * r + 0.72 * g + 0.07 * b); }Y su función de filtro se verá así:
function filter() { ..... var filtered = toGray(rgblist) imgData.data[i] = filtered imgData.data[i+1] = filtered imgData.data[i+2] = filtered .... }