设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 11158|回复: 0

Canvas绘制像素风图片的示例代码

[复制链接]

83

主题

0

回帖

261

积分

中级会员

Rank: 3Rank: 3

积分
261
发表于 2022-3-26 10:59:44 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
前言

童年玩红白机。尤其国内的小霸王那段时光还记得么。
那个马里奥大叔还记得么。

因为特别喜欢像素风的游戏从小到大一直都是,像素风本身就是由极度简单的元素构成极度复杂的画面,因此它可以具备无限的创作空间,形成令人过目不忘的独特画风。所以我想借用一张清晰的图片生成出具有像素点阵的图片来批量制造。
这是我写的第一篇短文,很多不足之处请多包涵。
介绍

怎么让清晰的图片转化成像素风格的图片呢?
首先我们要了解到像素风是由简单的单一色块来构成的。

所以我们第一就是上传一张图片,然后绘制出来。再解析每隔一定像素给图片取出色值和位置来。再将这些色值重新绘制到画布相应位置中,那么一张像素风就是这么简单实现了。
实现

1. 上传原图片
  1. <input type="file" accept=".jpeg,.jpg,.png" />
  2. <script>
  3. document.querySelector("input[type=file]").addEventListener("change",uploadImage, false);
  4. </script>
复制代码
首先我们先要在页面放置一个上传文件得input。这些用accept属性限制他得上传类型,因为涉及到常规的一些图片上传这里就传jpeg,jpg,png三种格式了。
与此同时,要监听他的改变从而拿到所需要转换的文件。
接下来我将定义一个uploadImage函数。
  1. function uploadImage(e) {
  2.     let file = e.target.files[0];
  3.     if (!file) return;
  4.     let fileReader = new FileReader();
  5.     fileReader.readAsDataURL(file);
  6.     fileReader.onload = () => {
  7.         createImage(fileReader);
  8.         e.target.value = "";
  9.         document.querySelectorAll("canvas").forEach(node=>{node.remove();})
  10.     };
  11. }

  12. function createImage(obj) {
  13.     let img = new Image();
  14.     img.onload = () => {
  15.         drawImage(img);
  16.     };
  17.     img.src = obj.result;
  18. }
复制代码
这里我们就可以在fileReader.result拿到上传后的图片地址了,再写一个createImage函数用来接收文件对象实例化成Image方便给画布绘制。毕竟一个函数尽量只做单一的一件事也算是个好习惯吧。
2.绘制原图片
  1. function drawImage(img) {
  2.         let canvas = document.createElement("canvas");
  3.         let ctx = canvas.getContext("2d");
  4.         canvas.width = ctx.width;
  5.         canvas.height = ctx.heigh
  6.         let w = img.width,
  7.           h = img.height;
  8.         ctx.drawImage(img,0,0,w,h);
  9.         document.body.appendChild(canvas);
  10. }
复制代码

我们先实现把图片绘制到画布上康康,到底啥样。现在我们就想了,我们到底要生成多大的像素画呢。这里我们想做一个全局变量吧。
  1. let width = 32;
  2. let height = 32;
  3. let size = 10;
复制代码
我们定义生成一个宽度,高度,像素尺寸。宽高故名思议,就是我们要生成多少宽多少个点,高多少个点的像素。size表示了一个像素填充多大,也就是每隔size个像素取一个色值。
接下来我们改造一下drawImage函数。
  1. function drawImage(img) {
  2.     let canvas = document.createElement("canvas");
  3.     let ctx = canvas.getContext("2d");
  4.     canvas.width = ctx.width = width * size;
  5.     canvas.height = ctx.height = height * size;
  6.     let w = img.width,
  7.         h = img.height;
  8.     let v = w / h;
  9.     if (v > 1) {
  10.         w = width;
  11.         h = w / v;
  12.     } else {
  13.         h = height;
  14.         w = h * v;
  15.     }
  16.     ctx.drawImage(
  17.         img,
  18.         ((width - w) / 2) * size,
  19.         ((height - h) / 2) * size,
  20.         w * size,
  21.         h * size
  22.     );
  23.     document.body.appendChild(canvas);
  24.    
  25.     let pxMap = createPxMap(ctx);
  26.     drawPXCanvas(pxMap)
  27. }
复制代码
我们期望绘制图片后生成一套个包含像素信息的数组返回出来,然后我们再进行像素风的生成。
当然我们为了两张图做对比,把原图宽高也和像素图拉平,并且居中显示在画布中。
3.绘制像素画
  1. function createPxMap(ctx){
  2.     let pxMap = [];
  3.     for (let i = 0; i < width * size; i += size) {
  4.         for (let j = 0; j < height * size; j += size) {
  5.             let pixel = ctx.getImageData(i, j, 1, 1).data;
  6.             let color = `rgba(${pixel[0]},${pixel[1]},${pixel[2]},${pixel[3]/255})`;
  7.             pxMap.push({ x: i / size, y: j / size, color });
  8.         }
  9.     }
  10.     return pxMap;
  11. }
复制代码
我首先要得到点的位置和颜色信息,ctx.getImageData可以获取到一个buffer数组,0-3位分别代表红,绿,蓝,透明度的信息。我们要将这些信息存储起来。
到了最后我们终于要可以绘制像素画了。
  1. function drawPXCanvas(pxMap) {
  2.     let canvas = document.createElement("canvas");
  3.     let ctx = canvas.getContext("2d");
  4.     canvas.width = ctx.width = width * size;
  5.     canvas.height = ctx.height = height * size;
  6.     pxMap.forEach((px) => {
  7.         const { color, x, y } = px;
  8.         ctx.fillStyle = color;
  9.         ctx.fillRect(x*size, y*size, size, size);
  10.     });
  11.     document.body.appendChild(canvas);
  12. }
复制代码
我们要重新生成一个画布,将刚刚收集到的像素信息逐个绘制到画布上,这样一张简单的像素画就这么完成了,是不是很容易。

拓展

其实拿到像素信息的时候,可以不局限于canvas2d像素画了。
还有以下思路:
我们可以借助于css的box-shadow来生成像素画,用:root 或者scss 更容易控制大小和位置,配合animation生成动画也未尝不可。
甚至我们也可以拓展webgl的,生成3d像素,或者其他风格也未尝不可。
3d皮卡丘
我们可以将再深入分析像素化构成逐帧生成视频和动画。。。
到此这篇关于Canvas绘制像素风图片的示例代码的文章就介绍到这了,更多相关Canvas 像素风内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!
                                                                                               
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表