将彩色图片转成黑白 |
您所在的位置:网站首页 › 纯黑色rgb值图片 › 将彩色图片转成黑白 |
在数字化发达的今天,黑白图像在我们日常生活中越来越少见了,黑白图像虽不比彩图的真实和美感,却能突出严肃和年代感,也更具纪念意义。本文将介绍如何在前端将彩色位图转为黑白,供有兴趣的小伙伴参考。 这是我参与更文挑战的第11天,活动详情查看: 更文挑战 实现思路话不多说,直接开搞。 位图其实是一个个的小格子(像素点)组成的图像:
所以,我们需要将位图中每个像素点的rgba转换为相应灰度的rgba。 如何计算呢? 我们采用均值法:将r、g、b三个值相加后取平均数作为新颜色值的rgb、alpha统一为不透明。 例如,将红色rgba(255,0,0,1)转为黑白色rgba(85,85,85,1) 接下来,我们需要拿到位图图像所有的rgba颜色值。 获取图像的颜色值这里我们需要借助一个方法ctx.getImageData(sx, sy, sw, sh):表示从cavas2d上下文获取某个区的图像数据。sx、sy表示该区域图像的起点,sw和sh表示该区域图像的尺寸。 我们要获取一张图片的rgba颜色值,该怎么做呢? 将这张图片绘制到canvas上 借助canvas2d渲染上下文的getImageData方法获取数据 var img = document.querySelector('img'); var canvas = document.querySelector('#canvas'); img.onload = function(){ var naturalImgSize = [img.naturalWidth,img.naturalHeight]; var ctx = canvas.getContext("2d"); canvas.width = naturalImgSize[0]; canvas.height = naturalImgSize[1]; ctx.drawImage(img,0,0); //获取imageData var imgData = ctx.getImageData(0,0,254,419); //打印该数据 console.log(imgData) }我们拿到的数据是这样的:
例如,我们有一个2px*2px的红色图片: 从左到右从上到下,它有4个像素点, 每个像素点包含rgba 4个值(一个字节表示一个值,范围从0-255,也就是00000000-11111111)。因此每个像素点要占4个位置。 该红色图像的rgba数据值对应的一维数组包含了4个255,0,0,255,即 [255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255]。 例证完毕,再回到我们拿到的Unit8ClampedArray数组,它的长度为图像的像素宽高*4:254*419*4 = 425704。 展开不就是一个个的0-255的数据点么:
上一节我们拿到了图像数据,接下来就是要执行灰度转换了,根据之前提到的,我们采用均值法。 我们需要遍历上述的数组,然后将换算后的值同步到一个新的数组里,再根据新数组生成一份新的imageData并渲染到canvas上即可。 //定义一个新的数组 let newArr = []; imgData.data.forEach((colorVal,i)=>{ if(i % 4 === 0){ // 获取rgb均值 const average = Math.round((imgData.data[i]+imgData.data[i+1]+imgData.data[i+2])/3); newArr[i] = newArr[i+1] = newArr[i+2] = average; //alpha值统一为255 newArr[i+3] = 255; } }) //新建一个imgData对象 var newImgData = ctx.createImageData(254,419) //将换算后的数据添加到新的imageData对象里 newImgData.data.set(newArr); //将新建的imageData绘制到画布上 ctx.putImageData(newImgData, 0, 0);这一切执行完毕,我们可以看到: 现在我们已经将图像转换为灰色的了,我们再将canvas上的图像保存为图像文件: canvas.toBlob(blob=>{ var a = document.createElement("a"); var file = new File([blob], "wife.jpeg"); a.href = URL.createObjectURL(file); a.download = "wife.jpg"; a.click() },"image/jpeg")看到我们成功将该图像保存到本地了: 彩色转黑白到这里基本结束了,我们借助getImageData的能力,实现了在前端直接操控rgba数据。 有了这个能力,一些操作如图像旋转、图像的水平、垂直轴对称转换等通常需要借助客户端软件如ps等才能完成,在前端也都能完成,因为这些操作本质只是改变图像的像素点排列而已。用图示很好解释: 原图: 向右旋转90度: 水平轴对称: 再总结一下彩色位图转换为黑色的几个步骤: 将image关联的图像文件绘制到一个canvas上 获取canvas上图像的imageData数据 将imageData数据的rgba部分均值计算后填充到你一个新数组里 将新数组填充到一个新的ImageData对象上 再将新的ImageData对象绘制回canvas元素 canvas转换成file对象本地保存最后,感谢阅读,如果对文中内容有任何的疑问欢迎留言讨论、不吝赐教;如果本文对你有帮助,麻烦点个赞,谢谢哦。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |