使用canvas打造一款像素风头像生成工具

网上曾有人讨论过那些头像自动生成是如何实现,有些是采用的注册ID的首字母直接生成,也有些是直接使用的头像数据库,那么如何来制作一个让每个用户的头像都不同的头像自动生成工具呢,于是我搅了搅脑汁,想到一个不知为谁所知的办法。

确定我们目前的技术栈

  1. canvas
  2. node
  3. 机器学习
  4. 一些前端的小操作 当我们发现我们不会机器学习的时候,这就很难受了,最好的想法是去爬取大量数据来训练我们的模型,算了,不做了,本系列到此为止。

开始设计我们所需的东西

我们的目标是要用vue来搭建一个像素风头像生成工具,这里直接使用Vue-cli作为前端的页面处理,express来进行提交数据的处理,这样的好处是为了使我们的开发更贴切我们的常规开发。

页面部分

这里我们直接在自动生成的Helloworld组件内去编写。

框架设定

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <canvas id="view" width="200px" height="200px"></canvas></br>
    <input type="email" name="email" placeholder="邮箱" v-model="email">
    <input type="password" name="password" placeholder="密码" v-model="password"></br>
    <a href="#" v-on:click="getHead">create</a>
  </div>
</template>
复制代码

页面的整体构架如此,我们想在页面没有显示头像之前不至于太过空荡,又不想去自定设计图,于是我们发现了vue的logo图,于是我打算对它像素化一番。

像素化原理

谈到像素化,这个算是本次制作的一个小重点,网上有的教程会告诉你如何对一张图进行像素化处理,原理如下:

  1. 页面分成数个矩形区域。
  2. 对页面中的像素值取中间值
  3. 然后对区域进行中间值重绘

以上方法在很多教程里屡见不鲜,但是这里却不是我们所需要的,因为有个更简单的方法。

1. 使用离屏的canvas来保存图片

    this.offCan=document.createElement('canvas');
    this.offCan.width=20;
    this.offCan.height=20;
    this.default_logo.src=logo;
    this.default_logo.onload =function(){
      _self.render();
    }
复制代码

也许会很奇怪为什么我的离屏canvas设置的宽高是20,这也是像素化的狠重要一步,下面会讲到。

      this.ctx=this.view.getContext('2d');
      this.o_ctx=this.offCan.getContext('2d');
      this.o_ctx.drawImage(this.default_logo,0,0,20,20);
      this.ctx.imageSmoothingEnabled = false;
      this.ctx.webkitImageSmoothingEnabled = false;
      this.ctx.msImageSmoothingEnabled = false;
      this.bitMap(this.o_ctx);
      this.ctx.drawImage(this.offCan,0,0,200,200);
复制代码

这里则是主要的逻辑部分,其中三步的设置是设置了主canvas的抗锯齿属性

2. 像素处理

        var arrayData=this.o_ctx.getImageData(0,0,20,20);
        var data = arrayData.data;
        for (var i = 0; i < data.length; i += 4) {
            var red = data[i];
            var green = data[i + 1];
            var blue = data[i + 2];
            var alpha = data[i + 3];

            data[i]     =  red ;    
            data[i + 1] =green ;
            data[i + 2] = blue; 
            data[i + 3] = alpha >= 208 ? 255 : 0;               
        }
        ctx.putImageData(arrayData, 0, 0);
复制代码

其中的玄机就是在data[i + 3] = alpha >= 208 ? 255 : 0;这一步。 canvas绘制的位图,所以在图像进行放大的时候,就会模糊,出现像素块,这也就是我们所需要的,我们利用这一原理,将图像绘制在小的画布上,通过设置alpha的阈值来筛选调部分可能导致模糊的部分,最后再绘制到主画布上的时候,就只剩一块一块的像素块了。

整体的效果图如下,是不感觉原生的input框很有感觉。

未完待续

工具demo的制作已经算是进入了比较难的一部分,如何对用户数据的处理并生成对应的头像数据,报一下当前的进度。

已经实现: 页面的布局,axios对express的数据请求与接受,头像局部数据的生成 正在实现:脸部数据的整合与渲染处理 未完成 :生成工具的局部优化

因为未完成,所以这里不放demo了,会在末尾篇内放出连接,也可以先去我的git里溜一溜 我的git

因为不知道大家喜欢什么类型的教程,所以出的时候,都需要去搜素,如果大家有喜欢的,可以告诉我,我来整理相关的教程与原理 不定期更新canvas与svg的相关技术教程,有实战型,也会有主原理型的,2d 2.5d 3d都会包含到,同时涉及的有 线性代数 物理 图形学等相关的基础知识。

欢迎各位客官收藏关注 投硬币包养

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值