canvas图像处理

最近在慕课网看到一个canvas图像处理的教程,现在总结一下。 不多说其它了,开始说代码吧。 以下canvasA是原图的画布,canvasB是处理后的图像的画布 RGB通道过滤

RGB通道过滤

function filter(){
            var imageData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            //Uncaught SecurityError: Failed to execute ‘getImageData‘ on ‘CanvasRenderingContext2D‘: The canvas has been tainted by cross-origin data.
            //跨域认为是被污染的
            var pixelData = imageData.data;

            for(var i=0; i<canvasB.width*canvasB.height; i++){
                pixelData[4*i+0] = 0;  //r
                // pixelData[4*i+1] = 0; //g
                pixelData[4*i+2] = 0;  //b
            }

            contextB.putImageData(imageData,0,0,0,0,canvasA.width,canvasA.height);
        }

可以看到其实就是获取了像素点时候,把需要过滤掉的颜色置零就可以了

灰度化

function greyEffect(){
            var imageData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            var pixelData = imageData.data;

            for(var i=0; i<canvasB.width*canvasB.height; i++){
                var r = pixelData[4*i+0];
                var g = pixelData[4*i+1];
                var b = pixelData[4*i+2];

                var grey = r*0.3 + g*0.59 + b*0.11;

                pixelData[4*i+0] = grey;
                pixelData[4*i+1] = grey;
                pixelData[4*i+2] = grey;
            }

            contextB.putImageData(imageData,0,0,0,0,canvasA.width,canvasA.height);
        }

  就是通过一条算灰度的公式算出灰度值,然后把它赋给像素的rgb。

黑白二值化

function blackEffect(){
            var imageData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            var pixelData = imageData.data;

            for(var i=0; i<canvasB.width*canvasB.height; i++){
                var r = pixelData[4*i+0];
                var g = pixelData[4*i+1];
                var b = pixelData[4*i+2];

                var grey = r*0.3 + g*0.59 + b*0.11;
                if( grey > 255 / 2){
                    v = 255;
                }else{
                    v = 0;
                }

                pixelData[4*i+0] = v;
                pixelData[4*i+1] = v;
                pixelData[4*i+2] = v;
            }

            contextB.putImageData(imageData,0,0,0,0,canvasA.width,canvasA.height);
        }

就是算出灰度后,判断一下灰度是否大于255/2。如果是就认为该点是亮色,置为白色,否则,置为黑色。

反色

function reverseEffect(){
            var imageData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            var pixelData = imageData.data;

            for(var i=0; i<canvasB.width*canvasB.height; i++){
                var r = pixelData[4*i+0];
                var g = pixelData[4*i+1];
                var b = pixelData[4*i+2];

                pixelData[4*i+0] = 255 - r;
                pixelData[4*i+1] = 255 - g;
                pixelData[4*i+2] = 255 - b;
            }

            contextB.putImageData(imageData,0,0,0,0,canvasA.width,canvasA.height);
        }

  就是把像素的rgb变成255-rgb,就得到了相反的颜色

模糊算法

function blurEffect(){
            //临时保存样板
            var tmpData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            var tmpPixelData = tmpData.data;

            var imageData = contextA.getImageData(0,0,canvasA.width,canvasA.height);
            var pixelData = imageData.data;

            var blurR = 4; //模糊半径
            var totalnum = (2*blurR+1)*(2*blurR+1); //参考的像素点
            for(var i=blurR; i<canvasB.height-blurR; i++){
                for(var j=blurR; j<canvasB.width-blurR; j++){

                    var totalr = 0, totalg = 0, totalb = 0;
                    for(var dx=-blurR; dx<=blurR; dx++){
                        for(var dy=-blurR; dy<=blurR; dy++){
                            var x = i + dx;
                            var y = j + dy;

                            var p = x*canvasB.width + y;
                            totalr += tmpPixelData[p*4+0];
                            totalg += tmpPixelData[p*4+1];
                            totalb += tmpPixelData[p*4+2];
                        }
                    }
                    pixelData[4*i+0] = totalr / totalnum;
                    pixelData[4*i+1] = totalg / totalnum;
                    pixelData[4*i+2] = totalb / totalnum;
                }
            }

            contextB.putImageData(imageData,0,0,0,0,canvasA.width,canvasA.height);
        }

  这个算法比之前的复杂许多,原理就是获取当前像素点周围的像素的rgb的平均值赋给当前像素点。

边缘检测
1.roberts算子

function roberts(){
            //获取像素点阵
            var imageData = contextA.getImageData(0,0,canvasB.width,canvasB.height);
            var pixelData = imageData.data;

            //算法核心
            for(var i = 0; i < canvasB.height-1; i++){
                for(var j = 0; j < canvasB.width-1; j++){
                    //获取需要像素下标
                    var target = 4*(i*canvasB.width+j); //左上
                    var member1 = 4*(i*canvasB.width+j+1); //右上
                    var member2 = 4*((i+1)*canvasB.width+j); //左下
                    var member3 = 4*((i+1)*canvasB.width+j+1); //右下

                    for(var k = 0; k < 3; k++){
                        var gx = pixelData[target+k] - pixelData[member3+k];
                        var gy = pixelData[member1+k] - pixelData[member2+k];
                        var vc = Math.abs(gx) + Math.abs(gy);
                        pixelData[target+k] = vc;
                    }

                }
            }

            contextB.putImageData(imageData,0,0,0,0,canvasB.width,canvasB.height);
        }

  这个算法更复杂了,什么阈值的我没看懂,没有用,发现效果还可以。

2.sobel算子

//sobel算子
        function sobel(){
            //获取像素点阵
            var imageData = contextA.getImageData(0,0,canvasB.width,canvasB.height);
            var pixelData = imageData.data;

            var fImageData = contextA.getImageData(0,0,canvasB.width,canvasB.height);
            var fData = fImageData.data; //拷贝pixelData
            //旋转后的卷积核
            var gxData = [
                         [1,0,-1],
                         [2,0,-2],
                         [1,0,-1]
                        ];
            var gyData = [
                         [1,2,1],
                         [0,0,0],
                         [-1,-2,-1]
                        ];
            //算法核心
            for(var i = 1; i < canvasB.height-1; i++){
                for(var j = 1; j < canvasB.width-1; j++){
                    //获取需要像素下标
                    var target = 4*(i*canvasB.width+j); 

                    var gx = [0,0,0]; //r,g,b
                    var gy = [0,0,0]; 

                    for(var dx = -1; dx <= 1; dx++){
                        for(var dy = -1; dy <= 1; dy++){
                            var x = i + dx;
                            var y = j + dy;
                            var p = 4*(x*canvasB.width + y);
                            //rgb分别计算
                            for(var k = 0; k < 3; k++){
                                gx[k] += (fData[p+k] * gxData[dx+1][dy+1]);
                                gy[k] += (fData[p+k] * gyData[dx+1][dy+1]);
                            }
                        }
                    }

                    for(var k = 0; k < 3; k++){
                        var vc = Math.abs(gx[k]) + Math.abs(gy[k]);
                        pixelData[target+k] = vc;
                    }

                }
            }

            contextB.putImageData(imageData,0,0,0,0,canvasB.width,canvasB.height);
        }

  效果:

demo演示

原文地址:https://www.cnblogs.com/githubMYL/p/9094738.html

时间: 2024-10-17 19:25:17

canvas图像处理的相关文章

canvas图像处理汇总

一.canvas的情况 canvas自从出来了之后,在前端的图像处理上面提供了各种各样的遍历,虽然很多的操作其实都是要应用到算法的,但是这个也给前端提供了很多的可能性,其中最终要的一个canvas函数(至少我认为)就是getImageData,这个函数可以提取图像每个像素的RGBA值.因为有这个函数所有才有丰富多彩的canvas图像处理. 二.预备知识  2.1 获取一个canvas对象 <canvas id="test"></canvas> <scrip

HTML5标签canvas图像处理

摘要: canvas可以读取图片后,使用drawImage方法在画布内进行重绘.本文介绍canvas的图像处理 drawImage drawImage() 方法在画布上绘制图像.画布或视频.drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸. 语法 在画布上定位图像: context.drawImage(img,x,y); 在画布上定位图像,并规定图像的宽度和高度: context.drawImage(img,x,y,width,height); 剪切图像,并在

HTML5实验室简介之Canvas图像处理(一)

作为一个前端,想必对HTML5都不陌生,特别是移动端,如今已经比较火了,捞金量远胜于PC端,与其说HTML5是一项Web新时代革命性的技术,不如说其是现代化Web应用的新理念:一方面结合JavaScript,前端的羽翼更加丰满:另一方面,跨终端将Web应用推向了一个新的高度:你看到的视觉将更加高端.大气.炫酷:你浏览时的交互体验将更加人性化:你的设备消耗大大降低,运行更流畅:总之,你会惊叹,同时你会很舒服!而这一切都是基于HTML5的! 作为一个小前端,才疏学浅,个人小站(花满楼:http://

基于canvas图像处理的图片展示demo

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

Atitit.attilax软件研发与项目管理之道

1. 前言4 2. 鸣谢4 3. Genesis 创世记4 4. 软件发展史4 5. 箴言4 6. 使徒行传 4 7. attilax书 4 8. 启示录4 9. 技术标准的7条原则4 9.1. 后向兼容性4 10. 软件之道5 11. 计算机科学导论(原书第3版5 12. 数字电路5 13. 通用管理学5 14. 项目管理5 15. 团队建设与人力资源管理5 16. 软件工程5 16.1. 软件编写5 16.2. 软件构件化理论与技术5 16.3. 软件与编程理论6 16.4. 理论原则6 1

Canvas绘图方法和图像处理方法(转)

转自:http://javascript.ruanyifeng.com/htmlapi/canvas.html 概述 Canvas API(画布)用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap). 使用前,首先需要新建一个canvas网页元素. <canvas id="myCanvas" width="400" height="200"> 您的浏览器不支持canvas!

Android图像处理(二)--Paint,Canvas,ColorMatrix详细

android开发中可能经常会用到这些东西; 一.介绍 Paint:画笔 Canvas:画布 Matrix:变换矩阵 Paint 根据我们要画的类型,我们可以选择不同的笔,比如大气磅礴的山水画,我们可以选择大头的毛笔:细腻入微的肖像画我们可以选择尖头的铅笔.并且根据我们想要的效果,我们在绘画的时候,还会选择不同的颜料或不同颜色的笔: 那么在程序中,Paint 就足以满足以上所有的需要,我们可以根据我们自己的需要去自行设置我们画笔的属性,首先来看看都能设置哪些属性: Public Construc

【一天一个canvas】图像处理教程(十二)

Canvas是一个功能相当强大的画布,任由你去书写,当然,他也支持了图像处理的功能. drawImage(image,Dx,Dy)://用于显示,有时会超出 drawImage(image,Dx,Dy,Dw,Dh)://用于缩放 drawImage(image,Sx,Sy,Sw,Sh,Dx,Dy,Dw,Sh)://用于剪裁.缩放.显示 注:image是一个图像对象: Dx是画布中的x坐标,Dy是画布中的y坐标,Dw是图像在画布中的宽度,Dy是图像在画布中的高度,Sx,Sy,Sw,Sh分别是原图像

Canvas API

概述 绘图方法 图像处理方法 drawImage方法 getImageData方法,putImageData方法 toDataURL方法 save方法,restore方法 像素处理 灰度效果 复古效果 红色蒙版效果 亮度效果 反转效果 参考链接 概述 Canvas API(画布)用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap). 使用前,首先需要新建一个canvas网页元素. <canvas id="myCanvas"