视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
HTML5实现一个图片滤镜效果的示例代码分享
2020-11-27 15:10:25 责编:小采
文档


http://www.gxlcms.com/wiki/1118.html" target="_blank">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:233711
 */
 
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:233711
 * 图片滤镜效果
 * 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.1); //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();
 }
}

下载本文
显示全文
专题