一、理解颜色
我们在电脑屏幕上可以看到色彩斑斓的图像,其实这些图像都是由一个个像素点组成的。那么像素是什么?颜色又是什么呢?(如果您提出这两个问题,您一定是个热爱思考的人)一个像素其实对应着内存中的一组连续的二进制位,由于是二进制位,每个位上的取值当然只能是 0 或者 1 了!这样,这组连续的二进制位就可以由 0 ,1 排列组合出很多种情况,而每一种排列组合就决定了这个像素的一种颜色。先看看下面这幅图
我们可以看到这幅图描述了六个像素点,一共由24个小方框组成。
注意:图中的一个小方框代表一个字节,即8个二进制位。
因此,每个像素点由四个字节组成。图中也分别标出了这四个字节代表的含义:
第一个字节决定像素的红色值
第二个字节决定像素的绿色值
第三个字节决定像素的蓝色值
第四个字节决定像素的透明度值
每一种分颜色值的大小是从 0 到 255(提问:为什么只能到255?) ,透明度的取值:0 代表完全透明,255代表完全不透明。这样,我们就可以用(255,0,0,255)来表示一个纯红色像素,在内存中,他是这样的一个32位的串: 11111111 00000000 00000000 11111111 。
二、操作像素
了解了颜色和像素的实质,我们就可以对图形进行更加复杂的处理。可是,HTML5 目前还没有提供类似 setPixel 或者 getPixel 这样直接操作像素点的方法, 但是我们也有办法,就是使用 ImageData 对象:
ImageData对象用来保存图像像素值,它有 width、height和 data 三个属性,其中 data 属性就是一个连续数组,图像的所有像素值其实是保存在 data 里面的。
data 属性保存像素值的方法和我们在前面图片中看到的一模一样:
imageData.data[index*4 +0]
imageData.data[index*4 +1]
imageData.data[index*4 +2]
imageData.data[index*4 +3]
上面取出了 data 数组中连续相邻的四个值,这四个值分别代表了图像中第 index+1 个像素的红色、绿色、蓝色和透明度值的大小。注意:index 从0 开始,图像中总共有 width * height 个像素,数组中总共保存了 width * height * 4 个数值
上下文对象 Context 有三个方法用来创建、读取和设置 ImageData 对象,他们分别是:
createImageData(width, height):在内存中创建一个指定大小的 ImageData 对象(即像素数组),对象中的像素点都是黑色透明的,即rgba(0,0,0,0)
getImageData(x, y, width, height):返回一个 ImageData 对象,这个 IamgeData 对象中包含了指定区域的像素数组
putImageData(data, x, y):将 ImageData 对象绘制到屏幕的指定区域上
三、一个简单的图像处理例子
上面说了这么多,我们用了解的知识来玩玩图像编程,或许有一天我们就要在 Chrome 中玩 PhotoShop 了。
程序大概是这个样子的:
1、将一幅图片绘制到一个 canvas 元素上,为了不引发安全错误(Security_ERR:DOM EXCEPTION 18),我用的是我博客顶部的横幅背景图片。你要运行这个例子,可能需要改成自己的图片
2、有四个滑动条,分别代表 GRBA 四个分量
3、拖动滑动条,图像中对应的颜色分量就会增加或者减少
4、如果图像变成透明,就会显示 canvas 元素的背景,我把这个背景设置成了我的头像,呵呵。
思路:其实就是用 getImageData 方法,将你想改变的那一块区域的像素数组取出来,然后根据你拖动的滑动条和滑动条的数值,来更改那一块区域里所有像素对应颜色分量的值。处理完毕后再用 putImageData 方法绘制到画布上,就是这么简单。
下面是代码:
< canvas id ="test1" width ="507" height ="348" style ="background-image:url(http://images.cnblogs.com/cnblogs_com/myqiao/262115/r_2204793492575248335.jpg)" > 你的浏览器不支持 < 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 " );
// 画布的宽度和长度
var width = parseInt(canvas.getAttribute( " width " ));
var height = parseInt(canvas.getAttribute( " height " ));
// 装入图像
var image = new Image();
image.onload = imageLoaded;
// 顶部背景图片
image.src = " /skins/Valentine/images/banner2.gif " ;
// 用来保存像素数组的变量
var imageData = null ;
function imageLoaded() {
// 将图片画到画布上
ctx.drawImage(image, 0 , 0 );
// 取图像的像素数组
imageData = ctx.getImageData( 0 , 0 , width, height);
}
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 >
四、绘制随机颜色的点
这个例子是在画布上随机选择一个点,然后再给他一个随机的颜色值,其实用到的方法和上面的例子大同小异,就是需求不同罢了。
下面是代码和程序实例:
< 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 " );
// 画布的宽度和长度
var width = parseInt(canvas.getAttribute( " width " ));
var height = parseInt(canvas.getAttribute( " height " ));
var imageData = ctx.createImageData(width, height);
function randomPixel(){
var x = parseInt(Math.random() * width);
var y = parseInt(Math.random() * height);
var index = y * width + x;
var p = index * 4 ;
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 );
}
function clearCanvas(){
ctx.clearRect( 0 , 0 ,width,height);
imageData = ctx.createImageData(width, height);
}
</ script >
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容