I'm trying to create a filter for canvas which draws a monochrome version of an image. I'm drawing the image, then iterating through the image data, then changing those rgb values to a gray, then placing the image data into the canvas. I need help on how to create the gray shade from the rgb values. I want a javascript solution.
My code:
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>
CodePudding user response:
Just find the average of the rgb values, then insert that as the red, green, and blue values to create gray.
Your new toGray function would be:
function toGray(vals) {
var r = vals[0]
var g = vals[1]
var b = vals[2]
return (r g b)/3
}
CodePudding user response:
There are three algorithms for converting color to grayscale basically.
lightness, average, luminosity method
The lightness method averages the most prominent and least prominent colors:
(max(R, G, B) min(R, G, B)) / 2The average method simply averages the values:
(R G B) / 3The luminosity method is a more sophisticated version of the average method. It also averages the values, but it forms a weighted average to account for human perception. We’re more sensitive to green than other colors, so green is weighted most heavily. The formula for luminosity is
0.21 R 0.72 G 0.07 B
According to the above calculation formula, the function will be:
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);
}
And your filter function will look like this:
function filter() {
.....
var filtered = toGray(rgblist)
imgData.data[i] = filtered
imgData.data[i 1] = filtered
imgData.data[i 2] = filtered
....
}
