手把手教你圖片轉ASCII碼圖


效果圖##

基本思路##

  1. 把圖片每個像素點的信息拿出來,最重要的是拿到rgb的值
  2. 把每個像素點由rgb轉成灰度圖像,即0-255
  3. 給0-255分級,把每個等級的像素點轉換成ascii碼,完成

實現##

第一步:獲取像素信息

經查閱,使用canvas的getImageData方法可完成此要求,如下

<canvas id="canvas"></canvas>
<script>
    var canvas=document.getElementById("canvas");
    var context=canvas.getContext("2d");
    canvas.width=800;
    canvas.height=800;
    context.rect(0,0,800,800);
    context.fillStyle="red";
    context.fill();

    console.log(context.getImageData(0,0,800,800))
</script>

上述代碼指在canvas中鋪滿背景色為red,同時用getImageData()方法輸出整個畫布800*800的每個像素點。在控制台我們可以看到console的結果:

我們看到長度為2560000,而我們的寬*高才640000,這是怎么回事,難道不是一個像素點對應getImageData()中的一位?我們把2560000/640000,得出的結果值為4,所以我們可以初步猜測,在getImageData()中,每個像素點對應着四位。繼續往下看

從圖中我們可以看出0123為一個循環,而此處我們的像素點位紅色,根據r(紅)g(綠)b(黑),紅色的rgb應該為(255,0,0),所以0-3對應rgb的三個顏色取值,而第四個值應該是指代a(透明度)。

以上,我們完成了getImageData()的初步認識

擴展:使用getImageData()做反轉圖

首先反轉的意思是指,把每個像素點的每個rgb值都與255相減(alpha的值不改變),減完之后的值再次組成圖片,此時得到的新圖片就是我們的反轉圖片。

方法如下:

<canvas id="canvas"></canvas>
<script>
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    canvas.width = 800;
    canvas.height = 800;
    var img = new Image();
    img.src = "love.png";
    img.onload =function(){
        invert(this);
    };
    //    像素點的rgba數組
    function invert(img) {
        context.drawImage(img,0,0);
        //獲取圖片對象以及元素點的數組
        var img1 = context.getImageData(0, 0, 800, 800);
        var data = img1.data;
        //反轉rgba
        for (var i = 0, len = data.length; i < len; i += 4) {
            data[i]=255-data[i];
            data[i+1]=255-data[i+1];
            data[i+2]=255-data[i+2];
        }
        context.putImageData(img1, 0, 0);
    }
</script>

這段代碼的關鍵點在於,要拿到圖片對象,並且取得該對象的data像素點數據,在原對象上對數據進行修改后,使用putImageData方法,把修改后的圖片對象賦給canvas

效果如下:

原圖

效果圖

如果我們可以做反轉圖了,那么也可以思考下一個問題,其實我們平時看的很多濾鏡效果,本質上就是改變像素點的rgba值,只是不同濾鏡效果的rgba算法不一樣,像我們現在做的這個反轉效果也可以算濾鏡的一種。

第二步:轉灰度圖

Gray Scale Image 或是Grey Scale Image,又稱灰階圖。把白色與黑色之間按對數關系分為若干等級,稱為灰度。灰度分為256階。用灰度表示的圖像稱作灰度圖。

簡單來說,灰度圖就是我們平時所說的黑白圖片,把普通圖片轉成灰度圖有以下幾種算法

1.浮點算法:Gray=R0.3+G0.59+B*0.11

2.整數方法:Gray=(R30+G59+B*11)/100

3.移位方法:Gray =(R76+G151+B*28)>>8;

4.平均值法:Gray=(R+G+B)/3;

5.僅取綠色:Gray=G;

有了上面我們的反轉圖的經驗,這次做灰度圖轉換其實也很簡單,代碼如下:

//轉換灰度圖
    for (var i = 0, len = data.length; i < len; i += 4) {
        var avg=(data[i]+data[i+1]+data[i+2])/3;
        data[i]=avg;
        data[i+1]=avg;
        data[i+2]=avg;
    }

效果圖:

第三步:分級轉換成字符表示

接下來便是轉成字符來表示,先把字符分成15級,即0-14,依次為

var arr=["M","N","H","Q","$","O","C","?","7",">","!",":","–",";","."];

那么要想把0-255轉換成0-14,由於Math.floor(255/18)`的結果值為14,方法如下:

var avg=(data[i]+data[i+1]+data[i+2])/3;
var num=Math.floor(avg/18);

所以基本代碼如下(注意換行的方法):

function invert(img) {
    context.drawImage(img,0,0);
    //獲取圖片對象以及元素點的數組
    var img1 = context.getImageData(0, 0, 300, 300);
    var data = img1.data;
    //轉換灰度圖
    var arr=["M","N","H","Q","$","O","C","?","7",">","!",":","–",";","."];
    var result=[];
    for (var i = 0, len = data.length; i < len; i += 8) {
        var avg=(data[i]+data[i+1]+data[i+2])/3;
        var num=Math.floor(avg/18);
        result.push(arr[num]);
        if(i%1200==0&&i!=0){
            result.push("<br>")
        }
    }
    opt.innerHTML=result.join();
    document.body.appendChild(opt);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM