canvas学习笔记:canvas对图片的像素级处理--ImageData的应用
学习了canvas的基本绘图功能后,惊喜的发现canvas对图片数据也有相当强大的处理功能,能够从像素级别操作位图,当然[lte ie8]不支持。
主要的函数有三个:
ctx.createImageData(width,height); // 用于创建ImageData对象
ctx.getImageData(x,y,width,height); // 用于从canvas中获取ImageData对象
ctx.putImageData(imagedata, x, y, dx, dy, width, height); // 用于将ImagaData对象的数据填写到canvas中,起到覆盖canvas中原图像的作用,可以只输入前三个参数。参数分别是:用于提供填充图像数据的imagedata对象,imagedata对象左上角相对于canvas左上角的坐标x,y,在canvas上用来填充imagedata区域的左上角相对imagedata对象左上角的坐标x,y(相对于canvas左上角),填充区域的长度和宽度。具体用法效果往下看。
我是想给图片来个局部反相效果,就是那种有点吓人的胶卷底片的效果。
实现思路是将图片画到canvas上,获取canvas的ImageData对象,对每个像素的颜色值进行反相处理。
代码如下:
<script type="text/javascript">
/*
* @param {object} img 展示反相的图片
*/
function showRevertPic(img){
img.color = img.src; // 给img添加属性指向源文件
img.revert = createRevertPic(img); // 给img添加属性指向反相图片
img.onmouseout = function(){
this.src = img.revert;
}
img.onmouseover = function(){
this.src = img.color;
}
img.onmouseout(); // 默认展示一次图片反相
} /*
* @param {object} img 要实现反相的图片
*/
function createRevertPic(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0);
var c = ctx.getImageData(0, 0, img.width, img.height);
//chrome浏览器报错,ie浏览器报安全错误信息,原因往下看
for(var i = 0; i < c.height; ++i){
for(var j = 0; j < c.width; ++j){
var x = i*4*c.width + 4*j, //imagedata读取的像素数据存储在data属性里,是从上到下,从左到右的,每个像素需要占用4位数据,分别是r,g,b,alpha透明通道
r = c.data[x],
g = c.data[x+1],
b = c.data[x+2];
c.data[x+3] = 150; //透明度设置为150,0表示完全透明
//图片反相:
c.data[x] = 255-r;
c.data[x+1] = 255-g;
c.data[x+2] = 255-b;
}
}
//ctx.putImageData(c, 40, 40);
ctx.putImageData(c,0,0,40,40,200,300); //裁剪效果见图1
return canvas.toDataURL(); //返回canvas图片数据url
}
window.onload=function() {
var img = new Image();
img.src = "boy.png";
img.isLoad = false;
document.body.appendChild(img);
img.onload=function(){
if(!img.isLoad){
showRevertPic(img);
img.isLoad=true;
}
}
}
</script>
间以上js文件复制到html文件中,然后在firefox浏览器打开就能看到一个漂亮的男孩(是的,不是女孩orz),底片一样的区域就是putImageData放置的区域,鼠标移上去就能看到原来的图片:

为什么img的onload函数要设置一个isLoad属性呢,原因你去掉isLoad的判断就知道了,你会发现,我擦咧,图片忽闪忽闪的,这个onload函数居然一直不断的执行下去。
为什么呢,因为showRevertPic(img)默认运行一次mouseout函数,而鼠标移入移出会导致图片的src的改变,每次src改变就会触发onload事件,而onload会导致图片再次反相,于是图片就一直忽闪忽闪的。而查看控制台,img的src一直指向64位编码的png图片数据而没有一次指向原图片地址,原因是当出发了一次mouseout函数img的src就不再指向源文件了,之后的变化是源图片的反相和源图片的反相的反相交替进行。所以给img设置了个isLoad属性是为了只触发一次showRevertPic()函数。
当然去掉showRevertPic()函数中的默认执行一次的mouseout函数也行,但是就不能立马看到图片的反相了。
这里其实存在跨域的问题,当用chrome浏览器或ie浏览器打开(9+)就会报错,
chrome:Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
ie:SCRIPT5022: DOM Exception: SECURITY_ERR (18)
指向错误愿意来自于getImageData只能操作与脚本位于同一个域中的图片,获取的图片是本地文件夹的,没有域名,所以浏览器认为跨域操作了。所以要感慨下,chrome和ie更注重安全性的问题啊。
解决方法是搭建服务器环境,将文件放到服务器目录下,通过服务器访问,这样就不会报错了。
现在说下createRevertPic()中的返回值canvas.toDataURL()。
这个方法返回的是canvas编码为图片数据的url,用来生成图片的,默认png格式,也可以通过传递参数改变图片格式,还能改变图片保存的质量。如:canvas.toDataURL("images/jpeg",0) ,第一个参数就是把图片编码为jpeg格式,第二个参数(0-1)就是指定图片质量,数值越大质量越高,不过对于image/png格式没得设置图片质量orz。另外,chrome还支持自家的image/webp格式图片,也能设置图片质量。
canvas.toDataURL("images/jpeg",0) 图片如下,这码打的可以吧:

拖延症的自救旅程之----新的篇章,但愿如此orz。
-------------------------------转载注明出处: http://www.cnblogs.com/suspiderweb/
canvas学习笔记:canvas对图片的像素级处理--ImageData的应用的更多相关文章
- canvas学习笔记、小函数整理
http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...
- SQL反模式学习笔记12 存储图片或其他多媒体大文件
目标:存储图片或其他多媒体大文件 反模式:图片存储在数据库外的文件系统中,数据库表中存储文件的对应的路径和名称. 缺点: 1.文件不支持Delete操作.使用SQL语句删除一条记录时,对应的文 ...
- canvas学习笔记(中篇) -- canvas入门教程-- 颜色/透明度/渐变色/线宽/线条样式/虚线/文本/阴影/图片/像素处理
[中篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- 【canvas学习笔记八】像素操作
ImageData对象 ImageData对象包含了一个区域内的canvas的像素信息.它包含以下可读属性: width canvas的宽度,单位是像素. height canvas的高度,单位是像素 ...
- 【canvas学习笔记五】使用图片
在canvas里画图有两个步骤: 获得图片源. drawImage()画图. 图片源 canvas支持以下几种图片资源: HTMLImageElement 可以使用Image()方法构造的图片,也可以 ...
- canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)
[下篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- canvas学习笔记
html5的新标签:canvas; 作用:标签定义图形,比如图表和其他图像:标签只是图形容器,您必须使用脚本来绘制图形.默认大小:宽300px,高150px; 背景知识:概念最初由苹果公司提出的,用于 ...
- canvas学习笔记:小小滴公式,大大滴乐趣
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近想弄一个网页,把自己学HTML5过程中做的部分DEMO放上去做集合,但是,如果就仅仅做个网页把所有DEMO一个一个排列又觉得太难看了. ...
- Android Bitmap和Canvas学习笔记 [转]
原文:http://www.cnblogs.com/feisky/archive/2010/01/10/1643460.html 位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的. ...
随机推荐
- 24章 创建TPL自定义模板(1)
鼓励分离 促进分工 smarty强大的模板引擎 自己开发可以深入了解模板引擎原理,并且简化(安全性,兼容性和功能不如开源的模板引擎) 流程图
- Netsuite > Hierarchy of transactions in Inventory cost calculation
First in day worksheets + Purchase Transactions (Receipts, Bills, Adjustments, Assembly Builds) + Tr ...
- Boost学习笔记(三) progress_timer
progress_timer也是一个计时器,它继承自timer,会在析构时自动输出时间,省去timer手动调用elapsed()的工作,是一个用于自动计时相当方便的小工具. #include < ...
- 遗传算法在JobShop中的应用研究(part 7:整体流程)
""" pop是种群,种群中的每个个体的形式是,(makespan, 染色体)""" pop = [(ComputeStartTimes(g ...
- LBWE更新模式切换问题:缓存清理
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 机电传动控制 PLC梯形图编程练习
交通灯控制 在如下图的场景中,打开SW1开关后,交通灯控制器开始工作,关闭SW1则控制器停止工作. 梯形图: 仿真结果: 可以满足所需要求. 输送带控制 输送带场景如下图: 梯形图: 仿真结果: 满足 ...
- 谈谈Web前端工程师的定位
原文地址:http://www.360doc.com/content/10/0708/17/1277406_37692580.shtml 2010-07-08 锋子chans 阅 1116 转 ...
- HTML基础(3)
1.块元素和内嵌元素(block\inline) 块的特征: 独占一行 不设定宽度,宽度将撑满整行 能设置所有样式 内嵌的特征: 默认同行可以继续跟同类型标签 内容撑开宽度 不支持宽高 不支持上下的m ...
- 利用CSS制作三角形
在我们看到类似于这样的图片时: 我们一般都会想,哎,这还不简单,用一张图片就可以了. 的确,用图片可以很轻松地做到.不过我们接下来要讨论的是: 如何用css也作出这样的效果. 首先,我们来定义一个 ...
- 扒一扒自从买了kindle后看的书
一.<性别战争> 讲述的是动物界各类动物的xxx(你懂的),以动物拟人化的口吻来进行问答,十分的生动形象,虽说和自己的生活没有多大联系,但是偶尔了解一下,也是意外的不错的感觉. 二.< ...