学习了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的应用的更多相关文章

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

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

  2. SQL反模式学习笔记12 存储图片或其他多媒体大文件

    目标:存储图片或其他多媒体大文件 反模式:图片存储在数据库外的文件系统中,数据库表中存储文件的对应的路径和名称. 缺点:     1.文件不支持Delete操作.使用SQL语句删除一条记录时,对应的文 ...

  3. canvas学习笔记(中篇) -- canvas入门教程-- 颜色/透明度/渐变色/线宽/线条样式/虚线/文本/阴影/图片/像素处理

    [中篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

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

    ImageData对象 ImageData对象包含了一个区域内的canvas的像素信息.它包含以下可读属性: width canvas的宽度,单位是像素. height canvas的高度,单位是像素 ...

  5. 【canvas学习笔记五】使用图片

    在canvas里画图有两个步骤: 获得图片源. drawImage()画图. 图片源 canvas支持以下几种图片资源: HTMLImageElement 可以使用Image()方法构造的图片,也可以 ...

  6. canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)

    [下篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  7. canvas学习笔记

    html5的新标签:canvas; 作用:标签定义图形,比如图表和其他图像:标签只是图形容器,您必须使用脚本来绘制图形.默认大小:宽300px,高150px; 背景知识:概念最初由苹果公司提出的,用于 ...

  8. canvas学习笔记:小小滴公式,大大滴乐趣

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近想弄一个网页,把自己学HTML5过程中做的部分DEMO放上去做集合,但是,如果就仅仅做个网页把所有DEMO一个一个排列又觉得太难看了. ...

  9. Android Bitmap和Canvas学习笔记 [转]

    原文:http://www.cnblogs.com/feisky/archive/2010/01/10/1643460.html 位图是我们开发中最常用的资源,毕竟一个漂亮的界面对用户是最有吸引力的. ...

随机推荐

  1. HTML 5 音频

    HTML 5 音频 ================================================================================= 音频是视频的重要 ...

  2. HTML 5 视频

    HTML 5 视频 ======================================================================================= 如今 ...

  3. oracle 删除用户时的坑

    ORACLE在使用 SELECT SID,SERIAL# FROM V$SESSION WHERE USERNAME='dt_zntg_trade' 删除会话时,一定要注意dt_zntg_trade的 ...

  4. Adobe Photoshop CC (32/64位) 绿色精简版

    32位版下载地址:http://pan.baidu.com/share/link?uk=33907222&shareid=3828486959 64位版下载地址:http://pan.baid ...

  5. php总结 --- 18. 七牛云存储

    第三方资源拉取 /** * 七牛云抓取文件 * @param string $url 文件URL地址 * * 参考地址:http://developer.qiniu.com/code/v6/api/k ...

  6. web-app子元素

    ?表示可选,最多一个:*表示0个或多个. web-app (icon?, display-name?, description?, distributable?, context-param*, fi ...

  7. maven引入本地jar

    mvn install:install-file -Dfile=***.jar -DgroupId=**.***.** -DartifactId=* -Dversion=0.8.11 -Dpackag ...

  8. Android之Dialer之紧急号码

    Android之Dialer之紧急号码 e over any other (e.g. supplementary service related) number analysis. a) 112 an ...

  9. ubuntu14.04利用aliyun安装docker

    docker官网上的安装步骤比较麻烦,而且下载下来后pull镜像也特别慢.通过阿里云可以快速安装docker,并且可配置加速器.通过阿里云超快速安装docker: 安装或升级Docker 请安装1.6 ...

  10. grep 使用或条件 ( grep -e )

    test@k1rhel5822161:/home/test>cat 31 52 33 24567test@k1rhel5822161:/home/test>grep -e '2|3' 3t ...