【canvas学习笔记八】像素操作

作者:分分快三计划

例子

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.onload = function() {
  draw(this);
};

function draw(img) {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
  var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  var data = imageData.data;

  var invert = function() {
    for (var i = 0; i < data.length; i  = 4) {
      data[i]     = 255 - data[i];     // red
      data[i   1] = 255 - data[i   1]; // green
      data[i   2] = 255 - data[i   2]; // blue
    }
    ctx.putImageData(imageData, 0, 0);
  };

  var grayscale = function() {
    for (var i = 0; i < data.length; i  = 4) {
      var avg = (data[i]   data[i   1]   data[i   2]) / 3;
      data[i]     = avg; // red
      data[i   1] = avg; // green
      data[i   2] = avg; // blue
    }
    ctx.putImageData(imageData, 0, 0);
  };

  var invertbtn = document.getElementById('invertbtn');
  invertbtn.addEventListener('click', invert);
  var grayscalebtn = document.getElementById('grayscalebtn');
  grayscalebtn.addEventListener('click', grayscale);
}

invert()反色函数将RGB通道的值用255减去,grayscale()去色函数将RGB通道的值进行平均,从而使颜色变成灰色。

 

结果

图片 1

点击grayscale按钮图片会变成灰色,点击invert按钮图片会反色。
可以把代码放进codepen里看看效果如何。

 

创建ImageData对象

有两种方法创建ImageData:

var myImageData = ctx.createImageData(width, height);

var myImageData = ctx.createImageData(anotherImageData);

注意啦,方法二是不会把data属性复制过去的,仅仅是复制了宽度和高度,data数组里的像素信息都是透明黑的,也就是都是0。

//==================================================

绘制像素

ctx.putImageData(myImageData, dx, dy);

这个方法可以传入一个ImageData对象,然后把ImageData对象中的像素信息都画出来。dx, dy是绘制的左上角坐标。
比如我们可以逐一改变ImageData对象中的值,从而改变了整个图象的颜色,再把它画出来。
这有什么用呢?对于要对像素进行的操作来说,这很方便。比如反色、去色等操作。

    //顶部背景图片

结果

图片 2
鼠标滑过就会显示rgba值。

图片 3图片 4随机颜色的点

获取像素信息

可以用getImageData()方法获取像素信息。

var myImageData = ctx.getImageData(left, top, width, height);

top和left就是所截取的画布部分的左上角坐标。

Tip:
超过画布区域返回的像素信息都是透明黑,也就是都是0。

这个例子是在画布上随机选择一个点,然后再给他一个随机的颜色值,其实用到的方法和上面的例子大同小异,就是需求不同罢了。

ImageData对象

ImageData对象包含了一个区域内的canvas的像素信息。它包含以下可读属性:

width
canvas的宽度,单位是像素。
height
canvas的高度,单位是像素。
data
一个Uint8ClampedArray的一维数组,包含了每个像素的RGBA值。

什么是Uint8ClampedArray?这个数组里的数值是8位的整型,而且值得范围在0和255之间。任何不在[0, 255]之间的数都会变成[0, 255]之间最接近的那个整型数。
0到255之间,那记录的自然是RGBA颜色数值啦。这个data数组是这样排列的,data[0]是第一排第一列的像素R通道的数值,data[1]第一排第一列的像素G通道的数值,data[3]是第一排第一列的像素的Alpha通道的数值。而data[4]是第一排第二列的像素的R通道数值,以此类推。
比如说,第50排第200列的像素的蓝色通道的值:

blueComponent = imageData.data[((50 * (imageData.width * 4)) (200 * 4)) 2];

另外,data也有length属性,就是data数组的长度。

3、拖动滑动条,图像中对应的颜色分量就会增加或者减少

例子

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
};
var color = document.getElementById('color');
function pick(event) {
  var x = event.layerX;
  var y = event.layerY;
  var pixel = ctx.getImageData(x, y, 1, 1);
  var data = pixel.data;
  var rgba = 'rgba('   data[0]   ', '   data[1]  
             ', '   data[2]   ', '   (data[3] / 255)   ')';
  color.style.background =  rgba;
  color.textContent = rgba;
}
canvas.addEventListener('mousemove', pick);

    function clearCanvas(){
        ctx.clearRect(0,0,width,height);
        imageData = ctx.createImageData(width, height);
    }
</script>

保存图片

canvas可以将画布保存成图片链接,图片链接可以用于标签或者下载。

canvas.toDataURL('image/png')
默认转换成的格式是png。
canvas.toDataURL('image/jpeg', quality)
也可以是别的图片格式。quality是图片品质,数值是0~1。0是最差的品质,1是最佳的品质。

也可以生成二进制对象:

canvas.toBlob(callback, type, encoderOptions)

蓝色:

第三个字节决定像素的蓝色值

图片 5图片 6简单的图像处理

第二个字节决定像素的绿色值

ImageData对象用来保存图像像素值,它有 width、height和 data 三个属性,其中 data 属性就是一个连续数组,图像的所有像素值其实是保存在 data 里面的。

data 属性保存像素值的方法和我们在前面图片中看到的一模一样:

这样,我们就可以用(255,0,0,255)来表示一个纯红色像素

下面是代码:

    var imageData = ctx.createImageData(width, height);

    function imageLoaded() {
        // 将图片画到画布上
        ctx.drawImage(image, 0, 0);

第一个字节决定像素的红色值

1、将一幅图片绘制到一个 canvas 元素上,为了不引发安全错误(Security_ERR:DOM EXCEPTION 18),我用的是我博客顶部的横幅背景图片。你要运行这个例子,可能需要改成自己的图片

    //画布的宽度和长度
    var width = parseInt(canvas.getAttribute("width"));
    var height = parseInt(canvas.getAttribute("height"));

声明:为本文为原创文章,作者保留所有权利!欢迎转载,转载请注明作者左洸和出处博客园

imageData.data[index*4 0]

putImageData(data, x, y):将 ImageData 对象绘制到屏幕的指定区域上

红色:

        //取图像的像素数组
        imageData = ctx.getImageData(0, 0, width, height);
    }

        imageData.data[p   0] = parseInt(Math.random() * 256);
        imageData.data[p   1] = parseInt(Math.random() * 256);
        imageData.data[p   2] = parseInt(Math.random() * 256);
        imageData.data[p   3] =parseInt(Math.random() * 256);
        ctx.putImageData(imageData,0,0);
    }

    //用来保存像素数组的变量
    var imageData=null;

下面是代码和程序实例:

三、一个简单的图像处理例子

    image.src = "/skins/Valentine/images/banner2.gif";

 

我们可以看到这幅图描述了六个像素点,一共由24个小方框组成。

imageData.data[index*4 2]

声明:为本文为原创文章,作者保留所有权利!欢迎转载,转载请注明作者左洸和出处博客园 

上面取出了 data 数组中连续相邻的四个值,这四个值分别代表了图像中第 index 1 个像素的红色、绿色、蓝色和透明度值的大小。

2、有四个滑动条,分别代表 GRBA 四个分量

getImageData(x, y, width, height):返回一个 ImageData 对象,这个 IamgeData 对象中包含了指定区域的像素数组

了解了颜色和像素的实质,我们就可以对图形进行更加复杂的处理。

在内存中,他是这样的一个32位的串: 11111111 00000000 00000000 11111111

    //装入图像
    var image = new Image();
    image.onload =imageLoaded;

 

注意:index 从0 开始,图像中总共有 width * height 个像素,数组中总共保存了 width * height * 4 个数值

第四个字节决定像素的透明度值

imageData.data[index*4 1]

上面说了这么多,我们用了解的知识来玩玩图像编程,或许有一天我们就要在 Chrome 中玩 PhotoShop 了。

透明:

    function randomPixel(){
        var x= parseInt(Math.random()*width);
        var y= parseInt(Math.random()*height);
        var index = y * width   x;
        var p = index * 4;

    //画布的宽度和长度
    var width = parseInt(canvas.getAttribute("width"));
    var height = parseInt(canvas.getAttribute("height"));

四、绘制随机颜色的点

每一种分颜色值的大小是从 0 到 255(提问:为什么只能到255?) ,透明度的取值:0 代表完全透明,255代表完全不透明

 

HTML5边玩边学(1):画布

绿色:

可是,HTML5 目前还没有提供类似 setPixel 或者 getPixel 这样直接操作像素点的方法, 但是我们也有办法

 

因此,每个像素点由四个字节组成。图中也分别标出了这四个字节代表的含义:

下面是前两篇的链接:

<canvas id="test1" width="507" height="348" style="background-image:url( <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器</canvas>
红色:<input type="range" min="1" max="100" onchange="colorChange(event,0)"/>
绿色:<input type="range" min="1" max="100" onchange="colorChange(event,1)"/>
蓝色:<input type="range" min="1" max="100" onchange="colorChange(event,2)"/>
透明:<input type="range" min="1" max="100" onchange="colorChange(event,3)"/>
<script type="text/javascript">
    //获取上下文对象
    var canvas = document.getElementById("test1");
    var ctx = canvas.getContext("2d");

HTML5边玩边学(2):基础绘图

你的浏览器不支持 <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

就是使用 ImageData 对象:

    function colorChange(event,offset){
        imageLoaded();
        for (var y = 0; y < imageData.height; y ) {
            for (x = 0;x < imageData.width; x ) {
                //index 为当前要处理的像素编号
                var index = y * imageData.width   x;
                //一个像素占四个字节,即 p 为当前指针的位置
                var p = index * 4;
                //改变当前像素 offset 颜色分量的数值,offset 取值为0-3
                var color = imageData.data[p   offset] * event.target.value / 50; 
                // 颜色值限定在[0..255]
                color = Math.min(255, color); 
                //将改变后的颜色值存回数组
                imageData.data[p   offset]=color
            }
        }
        //输出到屏幕
        ctx.putImageData(imageData, 0, 0);
    }
</script>

上下文对象 Context 有三个方法用来创建、读取和设置 ImageData 对象,他们分别是

图片 7

createImageData(width, height):在内存中创建一个指定大小的 ImageData 对象(即像素数组),对象中的像素点都是黑色透明的,即rgba(0,0,0,0)

你的浏览器不支持 <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

思路:其实就是用 getImageData 方法,将你想改变的那一块区域的像素数组取出来,然后根据你拖动的滑动条和滑动条的数值,来更改那一块区域里所有像素对应颜色分量的值。处理完毕后再用 putImageData 方法绘制到画布上,就是这么简单。

imageData.data[index*4 3]


 

提示:建议使用 Chrome 浏览器或者 Firefox 浏览器阅读本文,否则文中的样例程序可能无法看到运行效果。

 

一、理解颜色

我们在电脑屏幕上可以看到色彩斑斓的图像,其实这些图像都是由一个个像素点组成的。那么像素是什么?颜色又是什么呢?(如果您提出这两个问题,您一定是个热爱思考的人)一个像素其实对应着内存中的一组连续的二进制位,由于是二进制位,每个位上的取值当然只能是 0 或者 1 了!这样,这组连续的二进制位就可以由 0 ,1 排列组合出很多种情况,而每一种排列组合就决定了这个像素的一种颜色。先看看下面这幅图

4、如果图像变成透明,就会显示 canvas 元素的背景,我把这个背景设置成了我的头像,呵呵。

注意:图中的一个小方框代表一个字节,即8个二进制位。

<canvas id="test2" width="300" height="300" style=" background-color: black">你的浏览器不支持 <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器</canvas>
<input type="button" value="画随机点" onclick="interval=setInterval(randomPixel,1);" />
<input type="button" value="停止" onclick="clearInterval(interval);"/>
<input type="button" value="清除" onclick="clearCanvas();"/>
<script type="text/javascript">
    //获取上下文对象
    var canvas = document.getElementById("test2");
    var ctx = canvas.getContext("2d");

二、操作像素

程序大概是这个样子的:

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划