图像处理的滤镜算法
灰度滤镜
将颜色的RGB设置为相同的值即可使得图片为灰色,一般处理方法有:
1、取三种颜色的平均值
2、取三种颜色的最大值(最小值)
3、加权平均值:0.3R + 0.59G + 0.11*B
for(var i = 0; i < data.length; i+=4) { var grey = (data[i] + data[i+1] + data[i+2]) / 3; data[i] = data[i+1] = data[i+2] = grey; }
黑白滤镜
顾名思义,就是图片的颜色只有黑色和白色,可以计算rgb的平均值arg,arg>=100,r=g=b=255,否则均为0
for(var i = 0; i < data.length; i += 4) { var avg = (data[i] + data[i+1] + data[i+2]) / 3; data[i] = data[i+1] = data[i+2] = avg >= 100 ? 255 : 0; }
反向滤镜
就是RGB三种颜色分别取255的差值。
for(var i = 0; i < data.length; i+= 4) { data[i] = 255 - data[i]; data[i + 1] = 255 - data[i + 1]; data[i + 2] = 255 - data[i + 2]; }
去色滤镜
rgb三种颜色取三种颜色的最值的平均值。
for(var i = 0; i < data.length; i++) { var avg = Math.floor((Math.min(data[i], data[i+1], data[i+2]) + Math.max(data[i], data[i+1], data[i+2])) / 2 ); data[i] = data[i+1] = data[i+2] = avg; }
单色滤镜
就是只保留一种颜色,其他颜色设为0
for(var i = 0; i < canvas.height * canvas.width; i++) { data[i*4 + 2] = 0; data[i*4 + 1] = 0; }
高斯模糊滤镜
高斯模糊的原理就是根据正态分布使得每个像素点周围的像素点的权重不一致,将各个权重(各个权重值和为1)与对应的色值相乘,所得结果求和为中心像素点新的色值。我们需要了解的高斯模糊的公式:
function gaussBlur(imgData, radius, sigma) { var pixes = imgData.data, height = imgData.height, width = imgData.width, radius = radius || 5; sigma = sigma || radius / 3; var gaussEdge = radius * 2 + 1; var gaussMatrix = [], gaussSum = 0, a = 1 / (2 * sigma * sigma * Math.PI), b = -a * Math.PI; for(var i = -radius; i <= radius; i++) { for(var j = -radius; j <= radius; j++) { var gxy = a * Math.exp((i * i + j * j) * b); gaussMatrix.push(gxy); gaussSum += gxy; } } var gaussNum = (radius + 1) * (radius + 1); for(var i = 0; i < gaussNum; i++) { gaussMatrix[i] /= gaussSum; } for(var x = 0; x < width; x++) { for(var y = 0; y < height; y++) { var r = g = b = 0; for(var i = -radius; i<=radius; i++) { var m = handleEdge(i, x, width); for(var j = -radius; j <= radius; j++) { var mm = handleEdge(j, y, height); var currentPixId = (mm * width + m) * 4; var jj = j + radius; var ii = i + radius; r += pixes[currentPixId] * gaussMatrix[jj * gaussEdge + ii]; g += pixes[currentPixId + 1] * gaussMatrix[jj * gaussEdge + ii]; b += pixes[currentPixId + 2] * gaussMatrix[jj * gaussEdge + ii]; } } var pixId = (y * width + x) * 4; pixes[pixId] = ~~r; pixes[pixId + 1] = ~~g; pixes[pixId + 2] = ~~b; } } imgData.data = pixes; return imgData; } function handleEdge(i, x, w) { var m = x + i; if(m < 0) { m = -m; } else if(m >= w) { m = w + i -x; } return m; }
怀旧滤镜
for(var i = 0; i < imgData.height * imgData.width; i++) { var r = imgData.data[i*4], g = imgData.data[i*4+1], b = imgData.data[i*4+2]; var newR = (0.393 * r + 0.769 * g + 0.189 * b); var newG = (0.349 * r + 0.686 * g + 0.168 * b); var newB = (0.272 * r + 0.534 * g + 0.131 * b); var rgbArr = [newR, newG, newB].map((e) => { return e < 0 ? 0 : e > 255 ? 255 : e; }); [imgData.data[i*4], imgData.data[i*4+1], imgData.data[i*4+2]] = rgbArr; }
熔铸滤镜
公式:
r = r128/(g+b +1); g = g128/(r+b +1); b = b*128/(g+r +1);
for(var i = 0; i < imgData.height * imgData.width; i++) { var r = imgData.data[i*4], g = imgData.data[i*4+1], b = imgData.data[i*4+2]; var newR = r * 128 / (g + b + 1); var newG = g * 128 / (r + b + 1); var newB = b * 128 / (g + r + 1); var rgbArr = [newR, newG, newB].map((e) => { return e < 0 ? 0 : e > 255 ? 255 : e; }); [imgData.data[i*4], imgData.data[i*4+1], imgData.data[i*4+2]] = rgbArr; }
冰冻滤镜
公式:
r = (r-g-b)*3/2; g = (g-r-b)*3/2; b = (b-g-r)*3/2;
for(var i = 0; i < imgData.height * imgData.width; i++) { var r = imgData.data[i*4], g = imgData.data[i*4+1], b = imgData.data[i*4+2]; var newR = (r - g -b) * 3 /2; var newG = (g - r -b) * 3 /2; var newB = (b - g -r) * 3 /2; var rgbArr = [newR, newG, newB].map((e) => { return e < 0 ? 0 : e > 255 ? 255 : e; }); [imgData.data[i*4], imgData.data[i*4+1], imgData.data[i*4+2]] = rgbArr; }
连环画滤镜
公式:
R = |g – b + g + r| * r / 256 G = |b – g + b + r| * r / 256; B = |b – g + b + r| * g / 256;
for(var i = 0; i < imgData.height * imgData.width; i++) { var r = imgData.data[i*4], g = imgData.data[i*4+1], b = imgData.data[i*4+2]; var newR = Math.abs(g - b + g + r) * r / 256; var newG = Math.abs(b -g + b + r) * r / 256; var newB = Math.abs(b -g + b + r) * g / 256; var rgbArr = [newR, newG, newB]; [imgData.data[i*4], imgData.data[i*4+1], imgData.data[i*4+2]] = rgbArr; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 如何优雅地链式取值?
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论