资讯专栏INFORMATION COLUMN

Canvas 实现位图转像素画

ACb0y / 2669人阅读

摘要:灰度值的计算公式,由值计算阈值处理的方法实现阈值灰度计算公式去掉图透明将图像还原大小反锯齿处理小图经过放大默认是模糊的,将置为才能清晰显示像素点。

2016 年快结束了,最后一天总要留下点什么。

前段时间迷上像素画,折腾了好一段时间,后来思考了下,能不能用程序或者有什么图像处理软件能把一张图片直接转成像素风格?
于是先谷歌一下,在豆瓣发现了这个很棒的小站,教你画像素画,其中有朋友分享一个PS处理的方法:位图快速转像素,这个方法处理对比度强的图片效果是不错的,于是我按照同样的思路,尝试用Canvas来完成同样的效果,纯粹只是不想打开PS。

看最终效果 or 不想折腾PS的 快戳这里:图像转换像素图

思路

将一张图片缩小到一定的百分比,比如25%,这时候截图,图片将丢失一些像素信息,对的就是要这种效果。

使用PS的阈值功能,将此时的图片处理,在设置合适的阈值下,让图片达到最佳显示效果。

最后将图片放大至看到像素点,就能看到我们要的像素化效果。

那么,用Canvas怎么实现呢?

首先应该理解阈值的概念,阈值可以理解为临界值,大于临界值呈现一种状态,小于临界值又呈现另一种状态。PS中阈值可以将图片变成黑白图像,阈值的范围是0~255,假设阈值是192,则PS会将亮度小于192的像素点转成黑色,将亮度大于192的转成白色。

getImageData

CanvasImageData对象可以得到图像的所有信息,imageData.data是一个保存着图片像素信息的数组,数组中每个值的范围是0~255,每四个值表示一个像素点的颜色信息,格式是这样的:imageData.data = [像素点1的R, 像素点1的G, 像素点1的B, 像素点1的A, 像素点2的R, 像素点2的G, 像素点2的B, 像素点2的A, ... , 像素点n的A]

var pixel = ctx.getImageData(x, y, width, height);
putImageData

imageData.data数组做修改后,可以通过putImageData写入修改后的像素数据。

ctx.putImageData(imageData, x, y);
实现 缩小图像
var scale = 0.25;
ctx.drawImage(image, 0, 0, image.width * scale, image.height * scale);
灰度化并阈值处理

为了实现最终效果,我这里是将图片的所有像素信息先灰度化,替代亮度信息,然后每个像素点的灰度值与设定的阈值相比较,大于阈值的显示为白色,小于阈值的显示为黑色。

// 灰度值的计算公式,由rgb值计算
var gray = 0.299 * r + 0.587 * g + 0.114 * b;

阈值处理的方法实现:

/**
 * [convert description]
 * @param  {[type]} ctx       [description]
 * @param  {[type]} imageData [description]
 * @param  {[type]} threshold [阈值]
 * @return {[type]}           [description]
 */
function convert(ctx, imageData, threshold) {
    var data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
        // 灰度计算公式
        var gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 *data[i + 2];
        var color = gray >= threshold ? 255 : 0;
        var alpha = data[i + 3];
        data[i]     = color;                         // red
        data[i + 1] = color;                         // green
        data[i + 2] = color;                         // blue
        data[i + 3] = alpha >= threshold ? 255 : 0;  // alpha, 去掉png图透明
    }
    ctx.putImageData(imageData, 0, 0);
}
将图像还原大小
ctx.drawImage(image, 0, 0, image.width / scale, image.height / scale);
反锯齿处理

小图经过放大默认是模糊的,将imageSmoothingEnabled置为false才能清晰显示像素点。

ctx.imageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;

完整的代码已经上传至 github(https://github.com/chuiliu/the-pixel-art)

来,看效果(左图为原图):


对于对比度强的图片,不进行阈值处理也可以有不错的效果

最终效果还是可以,但是这个方法本身存在一定局限性,对于对比度不高的图片效果很差,几乎不适用。所以玩的时候是比较挑图片的。

在线版仅支持高版本浏览器,欢迎试玩,快戳这里

原文链接:Canvas 实现位图转像素画

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86740.html

相关文章

  • Canvas在移动端绘制模糊的原因与解决办法

    摘要:不过,在测试过程中却发现,在移动端的浏览器上,绘制的内容展示十分模糊如下图,经过分析之后发现是由于移动端高清屏幕引起的。这也是为什么高清屏更加细腻的原因。 由于一些移动端的兼容性原因,我们某个项目需要前端将pdf转换成在移动端页面可直接观看的界面。为了方便解决,我们采用了pdf.js这个插件,该插件可以将pdf转换成canvas绘制在页面上。不过,在测试过程中却发现,在移动端的浏览器上...

    Airmusic 评论0 收藏0
  • Canvas在移动端绘制模糊的原因与解决办法

    摘要:不过,在测试过程中却发现,在移动端的浏览器上,绘制的内容展示十分模糊如下图,经过分析之后发现是由于移动端高清屏幕引起的。这也是为什么高清屏更加细腻的原因。 由于一些移动端的兼容性原因,我们某个项目需要前端将pdf转换成在移动端页面可直接观看的界面。为了方便解决,我们采用了pdf.js这个插件,该插件可以将pdf转换成canvas绘制在页面上。不过,在测试过程中却发现,在移动端的浏览器上...

    jas0n 评论0 收藏0
  • JavaScript 编程精解 中文第三版 十七、在布上绘图

    摘要:贝塞尔曲线方法可以绘制一种类似的曲线。不同的是贝塞尔曲线需要两个控制点而不是一个,线段的每一个端点都需要一个控制点。下面是描述贝塞尔曲线的简单示例。 来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目原文:Drawing on Canvas 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2...

    habren 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<