【canvas学习笔记八】像素操作
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学习笔记八】像素操作的更多相关文章
- tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)
tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...
- 【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
- tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)
续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...
- Redis学习笔记八:集群模式
作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- java学习笔记07--日期操作类
java学习笔记07--日期操作类 一.Date类 在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可. public class T { public ...
- Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...
- canvas学习笔记、小函数整理
http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...
随机推荐
- Jetty启动报错排查org.eclipse.jetty.util.MultiException: Multiple exceptions
最近自己搭建了一个spring的项目,使用Maven做项目构建,使用JDK8,为了方便启动就使用jetty作为启动容器,但是却无意间步入了一个坑 [WARNING] Failed startup of ...
- 【Linux 网络编程】端口
(1)众所周知的端口:0~1023,这些端口由IANA分配和控制它们紧密绑定用于一些服务.常用这些端口的通讯 明确表明了某些协议.例如:21端口为ftp服务端口. (2)注册端口:1024~49 ...
- 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字
在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. package text; class Parent { int x; public Parent() { ...
- 如何根据对象的属性,对集合(list / set)中的对象进行排序
一:针对list 通过java.util.Collections的sort方法,有2个参数,第一个参数是list对象,第二个参数是new Comparator<对象类>(){}方法,这 ...
- [Codeforces 1245D] Shichikuji and Power Grid (最小生成树)
[Codeforces 1245D] Shichikuji and Power Grid (最小生成树) 题面 有n个城市,坐标为\((x_i,y_i)\),还有两个系数\(c_i,k_i\).在每个 ...
- wpf学习笔记(1)
wpf常用控件 0x01. 常用布局控件 1.Canvas 不会对子控件施加任何帮助,也不会施加任何限制 2.DockPanel 可以让子控件贴靠在自己四条边的任意一边 ,最后一个子控件充满剩余区域 ...
- oracle链接报错shared memory realm does not exist
问题描述: 前两天能够正常链接,今天来了突然不能链接,原因不详. 处理方法: 连接linux进行如下操作: 1.sqlplus /nolog 2.conn / as sysdba 3.startup ...
- js中过滤在输入框中过滤掉特殊表情
在页面输入text 时,经常会出现某些特殊符号例如:❤
- api接口统一封装
具体的接口api模块,例如authorization.js import axios from '../axiosWrapper' let prefix = process.env.API_ROOT ...
- kali 下安装 vmtools
网上的教程都是默认路径下的,kali是定制版本的,路径不同,所以首先要找到media下安装包的路径,然后进入该路下,将安装包复制到想要的路径下,并解压缩到想要的路径下,剩下的就跟网上的差不多了,即找到 ...