经查阅,使用canvas的getImageData方法可完成此要求,以下算法
<canvas id="canvas"></canvas> <script> var canvas=document.getElementById("canvas"); var context=canvas.getContext("2d"); canvas.width=800; canvas.height=800; context.rect(0,0,800,800); context.fillStyle="red"; context.fill(); console.log(context.getImageData(0,0,800,800)) </script>
上述代码指在canvas中铺满背景色为red,同时用getImageData()方法输出整个画布800*800的每一个像素点。在控制台咱们能够看到console的结果:canvas
咱们看到长度为2560000,而咱们的宽*高才640000,这是怎么回事,难道不是一个像素点对应getImageData()中的一位?咱们把2560000/640000,得出的结果值为4,因此咱们能够初步猜想,在getImageData()中,每一个像素点对应着四位。继续往下看数组
从图中咱们能够看出0123为一个循环,而此处咱们的像素点位红色,根据r(红)g(绿)b(黑),红色的rgb应该为(255,0,0),因此0-3对应rgb的三个颜色取值,而第四个值应该是指代a(透明度)。app
以上,咱们完成了getImageData()的初步认识this
扩展:使用getImageData()作反转图3d
首先反转的意思是指,把每一个像素点的每一个rgb
值都与255相减(alpha的值不改变),减完以后的值再次组成图片,此时获得的新图片就是咱们的反转图片。code
方法以下:对象
<canvas id="canvas"></canvas> <script> var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); canvas.width = 800; canvas.height = 800; var img = new Image(); img.src = "love.png"; img.onload =function(){ invert(this); }; // 像素点的rgba数组 function invert(img) { context.drawImage(img,0,0); //获取图片对象以及元素点的数组 var img1 = context.getImageData(0, 0, 800, 800); var data = img1.data; //反转rgba for (var i = 0, len = data.length; i < len; i += 4) { data[i]=255-data[i]; data[i+1]=255-data[i+1]; data[i+2]=255-data[i+2]; } context.putImageData(img1, 0, 0); } </script>
这段代码的关键点在于,要拿到图片对象,而且取得该对象的data像素点数据,在原对象上对数据进行修改后,使用putImageData
方法,把修改后的图片对象赋给canvasblog
效果以下:图片
原图
效果图
若是咱们能够作反转图了,那么也能够思考下一个问题,其实咱们平时看的不少滤镜效果,本质上就是改变像素点的rgba值,只是不一样滤镜效果的rgba算法不同,像咱们如今作的这个反转效果也能够算滤镜的一种。
Gray Scale Image 或是Grey Scale Image,又称灰阶图。把白色与黑色之间按对数关系分为若干等级,称为灰度。灰度分为256阶。用灰度表示的图像称做灰度图。
简单来讲,灰度图就是咱们平时所说的黑白图片,把普通图片转成灰度图有如下几种算法
1.浮点算法:Gray=R0.3+G0.59+B*0.11
2.整数方法:Gray=(R30+G59+B*11)/100
3.移位方法:Gray =(R76+G151+B*28)>>8;
4.平均值法:Gray=(R+G+B)/3;
5.仅取绿色:Gray=G;
有了上面咱们的反转图的经验,此次作灰度图转换其实也很简单,代码以下:
//转换灰度图 for (var i = 0, len = data.length; i < len; i += 4) { var avg=(data[i]+data[i+1]+data[i+2])/3; data[i]=avg; data[i+1]=avg; data[i+2]=avg; }
效果图:
接下来即是转成字符来表示,先把字符分红15级,即0-14,依次为
var arr=["M","N","H","Q","$","O","C","?","7",">","!",":","–",";","."];
那么要想把0-255转换成0-14,因为Math.floor(255/18)`的结果值为14,方法以下:
var avg=(data[i]+data[i+1]+data[i+2])/3; var num=Math.floor(avg/18);
因此基本代码以下(注意换行的方法):
function invert(img) { context.drawImage(img,0,0); //获取图片对象以及元素点的数组 var img1 = context.getImageData(0, 0, 300, 300); var data = img1.data; //转换灰度图 var arr=["M","N","H","Q","$","O","C","?","7",">","!",":","–",";","."]; var result=[]; for (var i = 0, len = data.length; i < len; i += 8) { var avg=(data[i]+data[i+1]+data[i+2])/3; var num=Math.floor(avg/18); result.push(arr[num]); if(i%1200==0&&i!=0){ result.push("<br>") } } opt.innerHTML=result.join(); document.body.appendChild(opt); }