黑白漫画去白底

对于黑白漫这类图片,如果放在一个背景不是白色的网页上,会显得很突兀,所以需要将图片的灰白色部分去除掉变成透明的。

另外也是因为在 iBooks 上体验到了这个功能,于是就自己写了一个简陋的版本。这里大致讲一些算法思路。

因为是要直接在浏览器上处理,所以就直接使用 JavaScript 写了。先获取 img 标签,再把得到的 Image 对象转换成 Canvas 对象,再通过 canvas 来处理像素块,得到去除白底的图片。

从 Canvas 里直接获取到的数据是 RGBA 格式(red-green-blue-alpha format)。

[255, 253, 255, 255, 252, 250, 252, 255, 254, 252, 254, 255, 255, 254, 255, 255, 255, 254, 255, 255, 254, 252, 254, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 253, 255, 255, 254, 252, 254, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 253, 255, 255, 255, 253, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 253, 255, 255, 253, 251, 253, 255…]

类似这样的 data

首先我们需要筛选出白色或偏灰色的像素,那么怎样的 RGBA 值算是符合要求的像素呢?,首先我们打开 Photoshop 玩玩自带的色盘。

左边红框的区域就是我们需要去除的目标颜色区域,而右边红框里的是 RGB 对应的色彩值。多玩玩色盘就能发现规律:RBA 三值同时处于 xxx(220)~255 之间的区域就是目标区域。所以写一个循环函数遍历所有像素并找出目标像素,将它的 Alpha 值设为 0。

如果需要判断这张图片是不是黑白漫画图片,同样是遍历所有像素进行统计,将像素点分为灰白像素点和黑彩像素点,再计算两者所占比例。如果大部分都是灰白色的像素点,则判断为目标图片。

使用 Canvas 的时候,值得注意的是图片的尺寸。当我们使用 <img> 标签嵌入一张图片的时候,有可能会将图片进行缩放,所以当用 Canvas 读取 Image 对象之后,应该用 naturalWidthnaturalHeight 来获取真实的图片尺寸,这样在处理图片生成 Canvas 的时候才不会模糊。同时再输出处理后的图片时,需要将 Canvas 的尺寸设置为缩放尺寸,通过设置 style 来实现

var width = img.naturalWidth;
var height = img.naturalHeight;

canvas.style.width = img.width + 'px';
canvas.style.height = img.height + 'px';

这样就可以得到一个粗糙版本的图片去白底程序了。

源代码 Github:https://github.com/moeoverflow/manga-image

接下来准备将这个东西做成 Hexo 的插件,在 hexo generate 的时候就生成好处理之后的 canvas,这样的好处就是,如果用户在访问你的网页时候网速很慢,那么在图片加载完之前,能看到的是原始带白底的图片。