专栏首页无人打理的花园[pixlate] 用 canvas 转像素画
原创

[pixlate] 用 canvas 转像素画

几周前看到这个像素猫的效果,这个版本的实现原理是 box-shadow,我想到用 grid 也可以实现一遍。接着发散到了“如何将任意图片像素化”上。

一开始的思路是如果还是用 grid 或者 box-shadow 的方式,需要遍历图片上的每个像素,拿到坐标和像素值,这样就需要用到 canvas。既然已经用到了 canvas… 其实就不用这么麻烦了,参考了 8-bit 的实现方法,可以用 drawImage 方法,将缩小的图片放大,通过 ctx.imageSmoothing = false 禁用掉浏览器器对图片平滑处理。

核心代码非常短:

var eightBit = function (canvas, image, scale) {
    scale *= 0.01;

    canvas.width = image.width;
    canvas.height = image.height;

		// 将图片缩小
    var scaledW = canvas.width * scale;
    var scaledH = canvas.height * scale;

    var ctx = canvas.getContext('2d');
  
		// 禁止浏览器的平滑处理
    ctx.mozImageSmoothingEnabled = false;
    ctx.webkitImageSmoothingEnabled = false;
    ctx.imageSmoothingEnabled = false;

    ctx.drawImage(image, 0, 0, scaledW, scaledH);
		// 但依然要画到和原图尺寸一样的画布上
    ctx.drawImage(canvas, 0, 0, scaledW, scaledH, 0, 0, canvas.width, canvas.height);
  };

背后的原理是将小尺寸的图片放到大尺寸的画布上,自然会“糊”,就像我们把 1x 的图片放在 Retina 屏幕上看一样。两者尺寸差别越大,模糊会越厉害,最极端的情况能到类似提取主题色那样的效果。因为要先缩小再真正画到画布上,所以先 draw image,再 draw canvas。从前我用 drawImage 基本画的都是媒体对象,这次画的是个 canvas 对象,对这个用法还蛮新奇的。根据 MDN,这个函数的第一个参数可以是任何的 canvas 图像源:

绘制到上下文的元素。允许任何的 canvas 图像源(CanvasImageSource),例如:CSSImageValueHTMLImageElementSVGImageElementHTMLVideoElementHTMLCanvasElementImageBitmap 或者OffscreenCanvas

如果不加上禁止平滑处理的话,出来的效果就会是这样,emm 谁把我的眼镜摘了:

CanvasRenderingContext2D.imageSmoothingEnabled 的文档里也说得很明白,如果开发者需要像素化的视觉效果,就需要禁用这个特性:

以缩放画布为例,这个属性对像素为主的游戏很有用。默认的改变大小的算法会造成图片模糊并且破坏图片原有的像素。 如果那样的话,设置属性值为false。 参见 CSS image-rendering 属性。

顺着这个属性,我爬到了 image-rendering 的文档页 — 哦!原来 image 也可以拿来这么处理啊。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • react-id-swiper 的使用

    github 地址,demo地址。支持多种场景,作者对 issues 的响应极快。

    kmokidd
  • zoom 和 transform: scale(x)

    一般设计师给到UI工程师的设计稿是基于 iPhone6 的,也就是说我们一般会先按照 375x667 的分辨率来定位页面上的元素。一开始在做活动页面的时候,我是...

    kmokidd
  • React 新手笔记

    团队的技术栈是 React saga + tcff(内部开源的框架,类似 dva)+ tea(内部开源的 UI 框架)

    kmokidd
  • canvas绘图不清晰的解决方案

    现象描述   同样大小的图片(60x60px)用canvas和DOM绘制,结果发现canvas的画面质量要差很多。结果如下图所示。 ?   上图中,左侧红框中的...

    用户1217459
  • Canvas基础教程(章节2)

      < canvas>会创建一个固定大小的画布,会公开一个或多个 渲染上下文(画笔),使用 渲染上下文来绘制和处理要展示的内容。   我们重点研究 2D渲染上...

    我不是费圆
  • C 中内存的一些操作

    分配内存与释放内存 在C 中,下列函数的声明在 stdlib.h 中,在 C++, 声明在 cstdlib 中 malloc realloc calloc f...

    ke1th
  • VBA实用小程序56: 删除多余空格

    下面的自定义函数:TrimAllSpace函数,可以将词语之间含有多个空格分隔的字符串整理成只有一个空格分隔词语的字符串,同时移除字符串开头和结尾处的空格。该函...

    fanjy
  • Spring Security权限框架理论与实战(三)-数据库管理1 UserDetailsService

    Spring Security中进行身份验证的是AuthenticationManager接口,ProviderManager是它的一个默认实现,但它并不用来处...

    JavaEdge
  • 开发 | 小程序做动画效果难?送你一个框架,10 分钟就能搞定

    在小程序中使用 canvas 绘制图案、动画的难度有目共睹。除了本身写法繁琐,小程序的技术特性,也使得小程序无法使用普通 HTML 5 的 canvas 框架,...

    知晓君
  • 短信轰炸之空格或\n绕过

    0x03 关键来了,这个时候在手机号后加一个空格,发现不提示次数超过限制了,并且验证码也发送成功了

    ittongluren

扫码关注云+社区

领取腾讯云代金券