HTML5实现一个图片滤镜效果的示例代码分享
html页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width = device-width,initial-scale=1.0"> </head> <body> <img src="img/5.jpg" class="photo"> </br> </br> <button class="reset">复位</button> </br> </br> <button class="grayscale">灰度效果</button> <button class="sepia">复古效果</button> <button class="redmask">红色蒙版效果</button> <button class="brightness">亮度效果</button> <button class="invert">反转效果</button> <button class="blackWhite">黑白效果</button> <button class="emboss">浮雕效果</button> </br> </br> <button class="redFilter">红色滤镜</button> <button class="greenFilter">绿色滤镜</button> <button class="blueFilter">蓝色滤镜</button> <button class="yellowFilter">黄色滤镜</button> <button class="perpleFilter">紫色滤镜</button> <button class="cyanFilter">青色滤镜</button> <script src="js/photoFilter.js"></script> <script src="js/app.js"></script> </body> </html>
app.js代码:
/** * Created by syo on 2017/3/14. * @author syo QQ:23371891 */ let photoData = new PhotoFilter(document.querySelector('.photo')); Array.prototype.slice.call(document.querySelectorAll('button')).map(function (dom, index) { dom.onclick = function (evt) { switch (evt.target.className) { case 'grayscale': photoData.grayscale(); break; case 'sepia': photoData.sepia(); break; case 'redmask': photoData.redmask(); break; case 'brightness': photoData.brightness(20); break; case 'invert': photoData.invert(); break; case 'blackWhite': photoData.blackWhite(100); break; case 'emboss': photoData.emboss(); break; case 'redFilter': photoData.redFilter(); break; case 'greenFilter': photoData.greenFilter(); break; case 'blueFilter': photoData.blueFilter(); break; case 'yellowFilter': photoData.yellowFilter(); break; case 'perpleFilter': photoData.perpleFilter(); break; case 'cyanFilter': photoData.cyanFilter(); break; case 'reset': photoData.reset(); break; } } })
photoFilter.js 类:
/** * Created by syo on 2017/3/14. * @author syo QQ:23371891 * 图片滤镜效果 * class PhotoFilter * @param img 传入img元素 */ class PhotoFilter { constructor(img) { "http://blog.51cto.com/viewpic.php?refimg=" + this.src = img.src; this.img = img; this.canvas = document.createElement('canvas'); this.ctx = this.canvas.getContext('2d'); this.canvas.width = this.img.width; this.canvas.height = this.img.height; this.drawImage(); } /** * 初始化 * 图片转canvas */ drawImage() { this.ctx.drawImage(this.img, 0, 0); this.imgData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height); } /** * 灰度 * 红、绿、蓝三个像素值的算术平均值 */ grayscale() { let d = this.imgData.data; for (let i = 0; i < d.length; i += 4) { let r = d[i]; let g = d[i + 1]; let b = d[i + 2]; d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3; } this.canvasToImage(); } /** * 复古 * 将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。 */ sepia() { let d = this.imgData.data; //假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值 for (let i = 0; i < d.length; i += 4) { let r = d[i]; let g = d[i + 1]; let b = d[i + 2]; d[i] = (r * 0.393) + (g * 0.769) + (b * 0.189); //red d[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168); //green d[i + 2] = (r * 0.272) + (g * 0.534) + (b * 0.131); //blue } this.canvasToImage(); } /** * 红色蒙版 * 图像呈现一种偏红的效果 * 算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为0 */ redmask() { let d = this.imgData.data; for (let i = 0; i < d.length; i += 4) { let r = d[i]; let g = d[i + 1]; let b = d[i + 2]; d[i] = (r + g + b) / 3; d[i + 1] = d[i + 2] = 0; } this.canvasToImage(); } /** * 亮度 * 图像变得更亮或更暗 * 算法将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值 * @param val 亮度值 */ brightness(val) { let d = this.imgData.data; for (let i = 0; i < d.length; i += 4) { d[i] += val; d[i + 1] += val; d[i + 2] += val; } this.canvasToImage(); } /** * 反相 * 图片呈现一种色彩颠倒的效果 * 算法为红、绿、蓝通道都取各自的相反值(255-原值) */ invert() { let d = this.imgData.data; for (let i = 0; i < d.length; i += 4) { d[i] = 255 - d[i]; d[i + 1] = 255 - d[i + 1]; d[i + 2] = 255 - d[i + 2]; } this.canvasToImage(); } /** * 黑白图片 * 求RGB平均值Avg = (R + G + B) / 3,如果Avg >= 100,则新的颜色值为R=G=B=255; * @param Threshold 阈值 */ blackWhite(threshold) { let d = this.imgData.data; for (let i = 0; i < d.length; i += 4) { let avg = (d[i] + d[i + 1] + d[i + 2]) / 3; d[i] = d[i + 1] = d[i + 2] = avg > threshold ? 255 : 0; } this.canvasToImage(); } /** * 浮雕效果 * 当前RGB减去相邻的GRB得到的值再加上128 * 取平均值 再次灰度,优化浮雕的效果 */ emboss() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { d[i] = d[i] - d[i + 4] + 128; d[i + 1] = d[i + 1] - d[i + 5] + 128; d[i + 2] = d[i + 2] - d[i + 6] + 128; let avg = (d[i] + d[i + 1] + d[i + 2]) / 3; d[i] = avg; d[i + 1] = avg; d[i + 2] = avg; } this.canvasToImage(); } /** * 红色滤镜 * 当前红色通道值变为原来的2倍 */ redFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let r = d[i] * 2; d[i] = r > 255 ? 255 : r; } this.canvasToImage(); } /** * 绿色滤镜 * 当前绿色通道值变为原来的2倍 */ greenFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let g = d[i + 1] * 2; d[i + 1] = g > 255 ? 255 : g; } this.canvasToImage(); } /** * 蓝色滤镜 * 当前蓝色通道值变为原来的2倍 */ blueFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let b = d[i + 2] * 2; d[i + 2] = b > 255 ? 255 : b; } this.canvasToImage(); } /** * 黄色滤镜 * 当前红色通道和绿色通道值+50 */ yellowFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let r = d[i] + 50; let g = d[i + 1] + 50; d[i] = r > 255 ? 255 : r; d[i + 1] = g > 255 ? 255 : g; } this.canvasToImage(); } /** * 紫色滤镜 * 当前红色通道和蓝色通道值+50 */ perpleFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let r = d[i] + 50; let b = d[i + 2] + 50; d[i] = r > 255 ? 255 : r; d[i + 2] = b > 255 ? 255 : b; } this.canvasToImage(); } /** * 青色滤镜 * 当前蓝色通道和绿色通道值+50 */ cyanFilter() { let d = this.imgData.data; for (let i = 4; i < d.length; i += 4) { let g = d[i + 1] + 50; let b = d[i + 2] + 50; d[i + 1] = g > 255 ? 255 : g; d[i + 2] = b > 255 ? 255 : b; } this.canvasToImage(); } /** * canvas转换成图片元素 */ canvasToImage() { this.ctx.putImageData(this.imgData, 0, 0); this.img.src = this.canvas.toDataURL(); } /** * 复原 */ reset() { this.img.src = "http://blog.51cto.com/viewpic.php?refimg=" + this.src; this.drawImage(); } }
以上是HTML5实现一个图片滤镜效果的示例代码分享的详细内容。更多信息请关注PHP中文网其他相关文章!