今晚原本想发「hybrid系列的jssdk文章」,可是被耽搁了,只写了一半,尚未完成。昨天朋友问js处理图片的问题,想起以前写过一篇canvas处理图片的文章,因而整理发了出来。下周文章预告:「hybrid系列的jssdk文章」html
html5的canvas能够进行图片处理,图片是由像素组成的。咱们知道canvas有方法 getImageData
,返回的对象中能够取出,image的data 数组(相似数组的Type Array类型数组,Uint8ClampedArray)。html5
假设canvas宽高是500*400,那么应该有200000个像素点,而经过 getImageData().data
获取的data数组的 length
是800000。web
咱们还知道rgba表示颜色的方法:算法
r=red,0~255canvas
g=green,0~255跨域
b=blue,0~255数组
a=alpha,0~100spa
即红绿蓝三原色和透明值。code
因此这个data数组是每四个数组值表明一个像素点。这样一来,一个图像就转化成了数据表示的数组。以下面的代码:htm
var canvas = document.getElementById('canvas');复制代码var ctxt = canvas.getContext('2d');复制代码var img = new Image;复制代码img.onload = function(){复制代码ctxt.drawImage(img, 0, 0);复制代码var data = ctxt.getImageData(0, 0, 480, 480).data;复制代码console.log(data, data.toString());复制代码}复制代码img.src = 'img/pic.jpg';复制代码
这里须要注意,图片src符合同源策略,即不能够跨域请求。
如上面的代码,咱们能够看到数组data就是图片转换成的数组,那么遍历这个数组就能够取得图片的像素点内容:
var data = ctxt.getImageData(0, 0, 480, 480).data;复制代码for(var i =0,len = data.length; i<len;i+=4){复制代码var red = data[i],复制代码green = data[i+1],复制代码blue = data[i+2],复制代码alpha = data[i+3];复制代码}复制代码
颜色反转的算法就是三原色求反,即 255-原色
。因此有了下面的方法:
function draw(img){复制代码ctxt.clearRect(0, 0, 480, 480);复制代码// console.log(img);复制代码ctxt.putImageData(img,0,0);复制代码}复制代码function invert(){复制代码var back = ctxt.createImageData(480, 480);复制代码var arr = back.data;复制代码for(var i=0,len = data.length;i<len;i+=4){复制代码var red = data[i],复制代码green = data[i+1],复制代码blue = data[i+2],复制代码alpha = data[i+3];复制代码arr[i] = 255-red;复制代码arr[i+1] = 255-green;复制代码arr[i+2] = 255-blue;复制代码arr[i+3] = alpha;复制代码}复制代码return back;复制代码}复制代码//颜色反转复制代码draw(invert());复制代码
把图片变成黑白图,只要把每一个像素的R、G、B设为亮度(Y)的值就好了。
关于R、G、B、Y的关系能够看到这里看看,这里只要记住这条公式: Y = 0.299R + 0.587G + 0.114B
,使用位: (R* 4899 + G * 9617 + B* 1868 + 8192) >> 14
,速度会快
就是将一个颜色换成它的补色。
补色就是用255(8位通道模式下,255即2的8次方,16位要用65535去减,即2的16次方)减去它自己获得的值: R(补) = 255 – R
。
其余算法须要基色和混合色配合能够参考:http://wenku.baidu.com/view/275f9c4769eae009581bec56.html
掘金更新比公众号晚一周左右。