将彩色图片转成黑白

您所在的位置:网站首页 纯黑色rgb值图片 将彩色图片转成黑白

将彩色图片转成黑白

2023-12-17 15:11| 来源: 网络整理| 查看: 265

在数字化发达的今天,黑白图像在我们日常生活中越来越少见了,黑白图像虽不比彩图的真实和美感,却能突出严肃和年代感,也更具纪念意义。本文将介绍如何在前端将彩色位图转为黑白,供有兴趣的小伙伴参考。

这是我参与更文挑战的第11天,活动详情查看: 更文挑战

实现思路

话不多说,直接开搞。

位图其实是一个个的小格子(像素点)组成的图像:

image.png 上图中的每个像素格子代表了一个颜色值,我们用rgba表示:r表示红色,g表示绿色,b表示蓝色,a表示透明度。

所以,我们需要将位图中每个像素点的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) }

我们拿到的数据是这样的: image.png height和width是图像的像素尺寸(254px * 419px),data就是图像rgba颜色值组成的一维数组。

例如,我们有一个2px*2px的红色图片:

image.png

从左到右从上到下,它有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的数据点么: image.png

执行转换

上一节我们拿到了图像数据,接下来就是要执行灰度转换了,根据之前提到的,我们采用均值法。

我们需要遍历上述的数组,然后将换算后的值同步到一个新的数组里,再根据新数组生成一份新的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);

这一切执行完毕,我们可以看到:

image.png

现在我们已经将图像转换为灰色的了,我们再将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")

看到我们成功将该图像保存到本地了:

image.png

总结

彩色转黑白到这里基本结束了,我们借助getImageData的能力,实现了在前端直接操控rgba数据。

有了这个能力,一些操作如图像旋转、图像的水平、垂直轴对称转换等通常需要借助客户端软件如ps等才能完成,在前端也都能完成,因为这些操作本质只是改变图像的像素点排列而已。用图示很好解释:

原图:

1.png

向右旋转90度:

2.png

水平轴对称:

3.png

再总结一下彩色位图转换为黑色的几个步骤:

将image关联的图像文件绘制到一个canvas上 获取canvas上图像的imageData数据 将imageData数据的rgba部分均值计算后填充到你一个新数组里 将新数组填充到一个新的ImageData对象上 再将新的ImageData对象绘制回canvas元素 canvas转换成file对象本地保存

最后,感谢阅读,如果对文中内容有任何的疑问欢迎留言讨论、不吝赐教;如果本文对你有帮助,麻烦点个赞,谢谢哦。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3