使用canvas打造一款畫素風頭像生成工具

山鬼發表於2018-05-11

網上曾有人討論過那些頭像自動生成是如何實現,有些是採用的註冊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的閾值來篩選調部分可能導致模糊的部分,最後再繪製到主畫布上的時候,就只剩一塊一塊的畫素塊了。

使用canvas打造一款畫素風頭像生成工具

整體的效果圖如下,是不感覺原生的input框很有感覺。

未完待續

工具demo的製作已經算是進入了比較難的一部分,如何對使用者資料的處理並生成對應的頭像資料,報一下當前的進度。

已經實現: 頁面的佈局,axios對express的資料請求與接受,頭像區域性資料的生成 正在實現:臉部資料的整合與渲染處理 未完成 :生成工具的區域性優化

因為未完成,所以這裡不放demo了,會在末尾篇內放出連線,也可以先去我的git裡溜一溜 我的git

因為不知道大家喜歡什麼型別的教程,所以出的時候,都需要去搜素,如果大家有喜歡的,可以告訴我,我來整理相關的教程與原理 不定期更新canvas與svg的相關技術教程,有實戰型,也會有主原理型的,2d 2.5d 3d都會包含到,同時涉及的有 線性代數 物理 圖形學等相關的基礎知識。

歡迎各位客官收藏關注 投硬幣包養

相關文章