资讯专栏INFORMATION COLUMN

canvas的图片处理

morgan / 675人阅读

摘要:对像素点实现基本的处理操作获取像素点数据获取中的像素信息,开始复制的左上角位置的坐标。灰度处理像素取反减去对应的值,再赋值给原来的亮度调节原来的值随机的加减一个相同的随机数。

canvas对像素点实现基本的处理操作
//       获取像素点数据
var canvas = document.getElementById("CanvasElt");
var ctx = canvas.getContext("2d");
//       获取canvas中的像素信息,
//x    开始复制的左上角位置的 x 坐标。
//y    开始复制的左上角位置的 y 坐标。
//width    将要复制的矩形区域的宽度。
//heigh将要复制的矩形区域的高度。
var canvasData = ctx.getImageData(x, y, canvas.width, canvas.height);
//       写入像素信息
ctx.putImageData(canvasData, 0, 0);
获取到的canvasData对象包含下列成员,其中的data数组结构大概是这样的,一行一行存,然后一个列点一个列点存,每个点占4个下标,分别是RGBA呗,则对于坐标(x,y)(这里的y是下方正向),RGBA分别是data[(ywidth+x)4],data[(ywidth+x)4+1],data[(ywidth+x)4+2],data[(ywidth+x)4+3]。 能够获取到像素点,就能对像素点进行操作,最简单的就是灰度处理了,灰度处理有很多种方式最简单的方法就是把每个相位的r,g,b相加取平均数,再分别赋给r,g,b。
//灰度处理
function gray() {
    var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
    for(var i = 0; i < imageData.data.length; i += 4) {
    var avg = (imageData.data[i] + imageData.data[i + 1] + imageData.data[i + 2]) / 3;
        imageData.data[i] = avg; // red
        imageData.data[i + 1] = avg; // green
        imageData.data[i + 2] = avg; // blue
        imageData.data[i + 3] = 255; //alpha
    }
    ctx1.putImageData(imageData, 0, 0);
}
像素取反:255 减去对应rgb的值,再赋值给原来的rgb;亮度调节:原来的rgb值随机的加减一个相同的随机数。那么想得到对比度变化的图片,或者模糊图片呢? 卷积核: 图片处理领域最常用的就是卷积核,所谓的矩阵的卷积,就是如下图显示的那样,当计算红色框中的数值的时候,分别先提取周围绿框中8个数字,然后与施加的那个矩阵中对应位置相乘,然后把各个乘积加在一起,就得到了最终的值了。
 
比如: (40 x 0)+(42 x 1)+(46 x 0)+ (46 x 0)+(50 x 0)+(55 x 0)+ (52 x 0)+(56 x 0)+(58 x 0)= 42 那怎么就能得到模糊的图片呢?图片的像素点和[1,1,1,1,1,1,1,1,1]的矩阵求卷积核,此时的像素点可能超过了255;所以再除以一个基数8;得到的图片就是加了模糊滤镜的图片;对比度呢,就是1.提高白色画面的亮度;2.让黑色更黑,降低最低亮度;可以求[0,0,0,0,3,0,0,0,0]的卷积核,同样的有可能超过255,再减去一个适合的基数150; 现在需要一个卷积核的函数: 函数第一个参数是 canvas上的 imageData 对象 第二个参数是传入矩阵所对应的数组,如果是下面这样的矩阵 a b c d e f g h i 则传入第二个的参数应为 [a,b,c,d,e,f,g,h,i] 第三个参数是除数因子。 第四个参数就是偏移量。
function ConvolutionMatrix(input, m, divisor, offset) {
    var output =document.createElement("canvas").getContext("2d").createImageData(input);
    var w = input.width,
        h = input.height;
    var iD = input.data,
        oD = output.data;
    for(var y = 1; y < h - 1; y += 1) {
        for(var x = 1; x < w - 1; x += 1) {
            for(var c = 0; c < 3; c += 1) {
                var i = (y * w + x) * 4 + c;
                // 卷积核计算
                oD[i] = offset +(m[0] * iD[i - w * 4 - 4] + m[1] * iD[i - w * 4] + m[2] * iD[i - w * 4 + 4] +m[3] * iD[i - 4] + m[4] * iD[i] + m[5] * iD[i + 4] +m[6] * iD[i + w * 4 - 4] + m[7] * iD[i + w * 4] + m[8] * iD[i + w * 4 + 4]) /divisor;
            }
                        oD[(y * w + x) * 4 + 3] = 255; // 设置透明度为不透明
        }
    }
    return output;
}
//模糊处理
function mohu(){
    var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
    var m = [1,1,1,1,1,1,1,1,1];
    var output = ConvolutionMatrix(imageData, m, 10,0);
    ctx1.putImageData(output,0,0);
}

//对比度处理
function level(){
    var imageData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
    var m = [0,0,0,0,3,0,0,0,0];
    var output = ConvolutionMatrix(imageData, m, 1,-150);
    ctx1.putImageData(output,0,0);
}
图片也可以有你想要的数据

既然图片每个像素都是由RGBA四个元素构成,单纯以图片来说用getImageData解析出来的只是一大堆你不必需要知道的数据,那么我们是不是可以把特定的色值看成我们自己的数据呢?
比如:在一张图片中,我们想把(r:255,g:255:b:255,a:255)白色像素找出来,可以通过getImageData来获取图片的数据,通过检索每个像素的数据是不是对应的rgba,把它们提取出来,再根据图片的宽度和高度,就可以计算出每个白色像素的位置信息,这些信息就是你想要提取的数据。

图片也需要做的好遍历些

在上一步中,我们已经知道了图片中特定元素获取相关位置信息的操作,但是图片是一个很普通的图片的话,你就需要遍历imageData中每个信息,有没有更好的方式减少遍历呢?
答案是:图片默认为黑色(r:0,g:0,b:0,a:0)就可以了,但不一定只有一个答案,或许也会有其他好的方法,但原理应该是一样的。
通过遍历每个像素的r,如果r!=0再去遍历这个像素的剩下的g,b,a,这一步比上一步剩下了无用的遍历,这一步中最重要的就是背景最好是黑色,因为黑色是全零状态,好计算。

还有没有更好的优化?

除了上述两步外,所用到的图片太大,也会导致遍历更多,而且我们只关心的是提取数据,而不关心他的大小,最终数据是我们想要的就行,那么我们可以把原图可以按比例缩放几倍,利用新的图片获取的数据最后在乘以相应的倍数,所得的就是我们想要的数据了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/54471.html

相关文章

  • web端上传图片图片被旋转问题

    摘要:有些时候在端上传图片会遇到这种情况,正向的图片,上传预览时就被旋转了。在使用或者其他软件旋转图片时,图片旋转了,但不会改变,由于我们使用的图片预览器能够预处理图片,使其看起来与旋转后一致,但上传图片时,浏览器并不会预处理。 有些时候在web端上传图片会遇到这种情况,正向的图片,上传预览时就被旋转了。 showImg(https://segmentfault.com/img/bVbhxd...

    CastlePeaK 评论0 收藏0
  • 基于node-canvas 和 express 一款图片格式转换工具

    摘要:基于和的一款图片格式转换工具完善后会发布成由于本项目当前是,还有很多不足支出,希望大家能指正,共勉。中请求发送必须使用发送数据并且在启动之前需要对做处理,使用做处理并且设置中的为这样后端才能正常接收并解析请求中所携带的数据。 基于node-canvas 和 express 的一款图片格式转换工具,完善后会发布成npm 由于本项目当前是Version@0.0.1,还有很多不足支出,希望大...

    zhoutk 评论0 收藏0
  • canvas图片处理

    摘要:对像素点实现基本的处理操作获取像素点数据获取中的像素信息,开始复制的左上角位置的坐标。灰度处理像素取反减去对应的值,再赋值给原来的亮度调节原来的值随机的加减一个相同的随机数。 canvas对像素点实现基本的处理操作 // 获取像素点数据 var canvas = document.getElementById(CanvasElt); var ctx = canvas.get...

    pingan8787 评论0 收藏0
  • canvas图片处理

    摘要:对像素点实现基本的处理操作获取像素点数据获取中的像素信息,开始复制的左上角位置的坐标。灰度处理像素取反减去对应的值,再赋值给原来的亮度调节原来的值随机的加减一个相同的随机数。 canvas对像素点实现基本的处理操作 // 获取像素点数据 var canvas = document.getElementById(CanvasElt); var ctx = canvas.get...

    Steve_Wang_ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<