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


Posted in HTML / CSS onSeptember 25, 2021

前言

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

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

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

介绍

怎么让清晰的图片转化成像素风格的图片呢?

首先我们要了解到像素风是由简单的单一色块来构成的。

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

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

实现

1. 上传原图片

<input type="file" accept=".jpeg,.jpg,.png" />
<script>
document.querySelector("input[type=file]").addEventListener("change",uploadImage, false);
</script>

首先我们先要在页面放置一个上传文件得input。这些用accept属性限制他得上传类型,因为涉及到常规的一些图片上传这里就传jpeg,jpg,png三种格式了。

与此同时,要监听他的改变从而拿到所需要转换的文件。

接下来我将定义一个uploadImage函数。

function uploadImage(e) {
    let file = e.target.files[0];
    if (!file) return;
    let fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = () => {
        createImage(fileReader);
        e.target.value = "";
        document.querySelectorAll("canvas").forEach(node=>{node.remove();})
    };
}

function createImage(obj) {
    let img = new Image();
    img.onload = () => {
        drawImage(img);
    };
    img.src = obj.result;
}

这里我们就可以在fileReader.result拿到上传后的图片地址了,再写一个createImage函数用来接收文件对象实例化成Image方便给画布绘制。毕竟一个函数尽量只做单一的一件事也算是个好习惯吧。

2.绘制原图片

function drawImage(img) {
        let canvas = document.createElement("canvas");
        let ctx = canvas.getContext("2d");
        canvas.width = ctx.width;
        canvas.height = ctx.heigh
        let w = img.width,
          h = img.height;
        ctx.drawImage(img,0,0,w,h);
        document.body.appendChild(canvas);
 }

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

我们先实现把图片绘制到画布上康康,到底啥样。现在我们就想了,我们到底要生成多大的像素画呢。这里我们想做一个全局变量吧。

let width = 32;
let height = 32;
let size = 10;

我们定义生成一个宽度,高度,像素尺寸。宽高故名思议,就是我们要生成多少宽多少个点,高多少个点的像素。size表示了一个像素填充多大,也就是每隔size个像素取一个色值。
接下来我们改造一下drawImage函数。

function drawImage(img) {
    let canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    canvas.width = ctx.width = width * size;
    canvas.height = ctx.height = height * size;
    let w = img.width,
        h = img.height;
    let v = w / h;
    if (v > 1) {
        w = width;
        h = w / v;
    } else {
        h = height;
        w = h * v;
    }
    ctx.drawImage(
        img,
        ((width - w) / 2) * size,
        ((height - h) / 2) * size,
        w * size,
        h * size
    );
    document.body.appendChild(canvas);
    
    let pxMap = createPxMap(ctx);
    drawPXCanvas(pxMap)
}

我们期望绘制图片后生成一套个包含像素信息的数组返回出来,然后我们再进行像素风的生成。
当然我们为了两张图做对比,把原图宽高也和像素图拉平,并且居中显示在画布中。

3.绘制像素画

function createPxMap(ctx){
    let pxMap = [];
    for (let i = 0; i < width * size; i += size) {
        for (let j = 0; j < height * size; j += size) {
            let pixel = ctx.getImageData(i, j, 1, 1).data;
            let color = `rgba(${pixel[0]},${pixel[1]},${pixel[2]},${pixel[3]/255})`;
            pxMap.push({ x: i / size, y: j / size, color });
        }
    }
    return pxMap;
}

我首先要得到点的位置和颜色信息,ctx.getImageData可以获取到一个buffer数组,0-3位分别代表红,绿,蓝,透明度的信息。我们要将这些信息存储起来。
到了最后我们终于要可以绘制像素画了。

function drawPXCanvas(pxMap) {
    let canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    canvas.width = ctx.width = width * size;
    canvas.height = ctx.height = height * size;
    pxMap.forEach((px) => {
        const { color, x, y } = px;
        ctx.fillStyle = color;
        ctx.fillRect(x*size, y*size, size, size);
    });
    document.body.appendChild(canvas);
}

我们要重新生成一个画布,将刚刚收集到的像素信息逐个绘制到画布上,这样一张简单的像素画就这么完成了,是不是很容易。

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

拓展

其实拿到像素信息的时候,可以不局限于canvas2d像素画了。

还有以下思路:

我们可以借助于css的box-shadow来生成像素画,用:root 或者scss 更容易控制大小和位置,配合animation生成动画也未尝不可。

甚至我们也可以拓展webgl的,生成3d像素,或者其他风格也未尝不可。

3d皮卡丘

我们可以将再深入分析像素化构成逐帧生成视频和动画。。。

到此这篇关于Canvas绘制像素风图片的示例代码的文章就介绍到这了,更多相关Canvas 像素风内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
HTML / CSS 相关文章推荐
全面解析CSS Media媒体查询使用操作(推荐)
Aug 15 HTML / CSS
让IE可以变相支持CSS3选择器
Jan 21 HTML / CSS
CSS3按钮鼠标悬浮实现光圈效果源码
Sep 11 HTML / CSS
CSS3动画:5种预载动画效果实例
Apr 05 HTML / CSS
纯css3制作煽动翅膀的蝴蝶的示例
Apr 23 HTML / CSS
使用spring mvc+localResizeIMG实现HTML5端图片压缩上传的功能
Dec 16 HTML / CSS
HTML5实现桌面通知 提示功能
Oct 11 HTML / CSS
SVG实现多彩圆环倒计时效果的示例代码
Nov 21 HTML / CSS
HTML5拍照和摄像机功能实战详解
Jan 24 HTML / CSS
Html5适配iphoneX刘海屏的简单实现
Apr 09 HTML / CSS
基于Html5 canvas实现裁剪图片和马赛克功能及又拍云上传图片 功能
Jul 09 HTML / CSS
html2 canvas svg不能识别的解决方案
Jun 03 HTML / CSS
Canvas如何做个雪花屏版404的实现
使用canvas对video视频某一刻截图功能
Sep 25 #HTML / CSS
使用CSS实现一个搜索引擎的原理解析
sass 常用备忘案例详解
Sep 15 #HTML / CSS
关于HTML编码导致的乱码问题
Sep 04 #HTML / CSS
使用CSS3实现按钮悬停闪烁动态特效代码
Aug 30 #HTML / CSS
深入理解CSS 中 transform matrix矩阵变换问题
Aug 30 #HTML / CSS
You might like
php mssql 日期出现中文字符的解决方法
2009/03/10 PHP
在命令行下运行PHP脚本[带参数]的方法
2010/01/22 PHP
Laravel5中防止XSS跨站攻击的方法
2016/10/10 PHP
让whoops帮我们告别ThinkPHP6的异常页面
2020/03/02 PHP
js原型继承的两种方法对比介绍
2014/03/30 Javascript
js实现遮罩层弹出框的方法
2015/01/15 Javascript
js模仿php中strtotime()与date()函数实现方法
2015/08/11 Javascript
JS+CSS实现滑动切换tab菜单效果
2015/08/25 Javascript
跟我学习javascript的基本类型和引用类型
2015/11/16 Javascript
jquery利用json实现页面之间传值的实例解析
2016/12/12 Javascript
JS实现异步上传压缩图片
2017/04/22 Javascript
微信小程序 新建登录页并实现tabBar隐藏
2017/06/13 Javascript
带你快速理解javascript中的事件模型
2017/08/14 Javascript
禁止弹窗中蒙层底部页面跟随滚动的几种方法
2017/12/07 Javascript
JS中获取 DOM 元素的绝对位置实例详解
2018/04/23 Javascript
基于React+Redux的SSR实现方法
2018/07/03 Javascript
CKEditor4配置与开发详细中文说明文档
2018/10/08 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
jquery传参及获取方式(两种方式)
2020/02/13 jQuery
Vue组件间数据传递的方式(3种)
2020/07/13 Javascript
[01:13:46]iG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python专用方法与迭代机制实例分析
2014/09/15 Python
Python编程之字符串模板(Template)用法实例分析
2017/07/22 Python
selenium+python实现自动登录脚本
2018/04/22 Python
利用Python读取txt文档的方法讲解
2018/06/23 Python
关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)
2020/02/20 Python
如何理解Python中包的引入
2020/05/29 Python
使用已经得到的keras模型识别自己手写的数字方式
2020/06/29 Python
canvas 橡皮筋式线条绘图应用方法
2019/02/13 HTML / CSS
Expedia瑞典官网:预订度假屋、酒店、汽车租赁、机票等
2021/01/23 全球购物
机械设计毕业生自荐信
2014/02/02 职场文书
实习生矿工检讨书
2014/10/13 职场文书
新员工试用期自我评价
2015/03/10 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL
Python Pygame实战在打砖块游戏的实现
2022/03/17 Python
js基于div丝滑实现贝塞尔曲线
2022/09/23 Javascript