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数组的长度。

创建ImageData对象

有两种方法创建ImageData:

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

var myImageData = ctx.createImageData(anotherImageData);

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

获取像素信息

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

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

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

Tip:

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

例子

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);

结果



鼠标滑过就会显示rgba值。

绘制像素

ctx.putImageData(myImageData, dx, dy);

这个方法可以传入一个ImageData对象,然后把ImageData对象中的像素信息都画出来。dx, dy是绘制的左上角坐标。

比如我们可以逐一改变ImageData对象中的值,从而改变了整个图象的颜色,再把它画出来。

这有什么用呢?对于要对像素进行的操作来说,这很方便。比如反色、去色等操作。

例子

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通道的值进行平均,从而使颜色变成灰色。

结果

点击grayscale按钮图片会变成灰色,点击invert按钮图片会反色。

可以把代码放进codepen里看看效果如何。

保存图片

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

canvas.toDataURL('image/png')

默认转换成的格式是png。

canvas.toDataURL('image/jpeg', quality)

也可以是别的图片格式。quality是图片品质,数值是0~1。0是最差的品质,1是最佳的品质。

也可以生成二进制对象:

canvas.toBlob(callback, type, encoderOptions)

【canvas学习笔记八】像素操作的更多相关文章

  1. tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)

    tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...

  2. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  3. tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)

    续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...

  4. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

  5. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  6. java学习笔记07--日期操作类

    java学习笔记07--日期操作类   一.Date类 在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可. public class T { public ...

  7. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  9. canvas学习笔记、小函数整理

    http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...

随机推荐

  1. java.time包常用类API学习记录

    Java8出来已那么多年了,java.time包之前一直没有使用过,最近正好有用到,在此做个记录. 上图列出了java.time包下的类,接下来我们详细看下其中每个类的用法. Clock:获取到当前时 ...

  2. MySQL出现 Access denied for user 'root'@'localhost' (using password:YES) 解决办法

    1.先停止MySQL服务,然后在MySQL安装目录(我的是C:\Program Files (x86)\MySQL\MySQL Server 5.1)找到my.ini文件,在最后一行添加skip-gr ...

  3. Excel透视表进阶之计算字段、计算项、切片器、页面布局

    计算字段 在透视表的字段列表中通过函数.公式等方式构建一个新的字段 又称虚拟字段,因为计算字段不会出现在数据源中,对于普通字段的操作,都可以对计算字段进行操作 计算字段只能出现在值区域,不能出现在筛选 ...

  4. BZOJ 4857 反质数序列

    题面 奇数+奇数一定不是质数(1+1除外),偶数+偶数一定不是质数,质数只可能出现在偶数+奇数中 把所有的点排成两列,权值为奇数的点在左边,权值为偶数的在右边 如果左边的点x+右边的点y是质数,我们就 ...

  5. frame的处理

    自动化测试时,有时会定位不到某些元素,是因为这些元素在frame中,所以必须先进入到frame中,才能再去定位要定位的元素. frame是页面的框架,即在一个浏览器的窗口显示多个页面,可以是水平框架和 ...

  6. luoguP4578_ [FJOI2018]所罗门王的宝藏

    题意 一个n*m的矩阵,初始值全为0,每一行每一列操作一次可以加1或者减1,问能否操作得到给定矩阵. 分析 行和列的分别的加减是可以相互抵消的,因此我们只需要考虑行的加和列的减. 对于给定矩阵每一个数 ...

  7. P1399 [NOI2013]快餐店

    传送门 基环树的题当然先考虑树上怎么搞,直接求个直径就完事了 现在多了个环,先把非环上的直径(设为 $ans$)和环上节点 $x$ 到叶子的最大距离(设为 $dis[x]$)求出来 考虑到对于某种最优 ...

  8. Dynamic Compilation and Loading of .NET Objects

      This is another approach to dynamic compilation of objects and their usage via Interfaces. Introdu ...

  9. vue-注册全局过滤器

    import Vue from 'vue'; import dayjs from 'dayjs'; const filters = { formatDate(date, format = 'YYYY- ...

  10. LVS实现负载均衡原理及安装配置 负载均衡

    LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...