使用骰子作画

本文参考 阮一峰老师《骰子作画的算法》

原文链接  骰子作画的算法 - 阮一峰的网络日志

计算灰度值方法

   /* 任何颜色都由红、绿、蓝三基色组成,假如原来某点的颜色为RGB(R,G,B),那么,我们可以通过下面几种方法,将其转换为灰度:
1.浮点算法:Gray=R*0.3+G*0.59+B*0.11
2.整数方法:Gray=(R*30+G*59+B*11)/100
3.移位方法:Gray =(R*77+G*151+B*28)>>8;
4.平均值法:Gray=(R+G+B)/3;
5.仅取绿色:Gray=G;*/

2.骰子作画算法

    1.第一步,将图片分割成16像素x16像素的小方块。  (分割的方块越小 ,模拟图生成的效果越好)

    2. 计算小方块内的每一个像素点  将每个像素点的灰度值存入数组

    3. 计算每一个小方块数组额灰度值的平均值  并用1~6之间的一个整数来表示 

    4. 用骰子绘制图片

 var canvas = document.createElement('canvas'); // 将分好的块绘制在画布上显示处来
    var context = canvas.getContext('2d');
    

    var poixl = [];
    // 获取图片的原始尺寸
    var nImg = new Image();
    // nImg.crossOrigin ='anonymous';
    nImg.src = './painting.jpg';
    var body = document.querySelector('body');

var w = 0,h = 0;
    var pieceW = 16; //切割小方块的边长
        var imgArr = []; // 绘制额小图标
        inintImg();
    nImg.onload = function(){
        w = nImg.width;
        h = nImg.height;
        canvas.width = w ;
        canvas.height = h ;
        b();
    }
    
    function inintImg(){
        var imgSrc = ['./img/t6.png','./img/t5.png','./img/t4.png','./img/t3.png','./img/t2.png','./img/t1.png'];
        for(let i = 0 ; i < imgSrc.length ; i++ ){
            var img = new Image();
            img.src = imgSrc[i];
            imgArr.push(img);
        }
    }
        
    // 第一步,将图片分割成16像素x16像素的小方块。
    function b(){
        let can; 
        let ctx;
        let wNum =  w/pieceW;
        let hNum = h/pieceW;
        for(let i = 0 ; i < wNum; i++){
            let arr1 = [];
            for(let j = 0 ; j < hNum; j++){
                can = document.createElement('canvas');
                        ctx = can.getContext('2d');
                        can.width = pieceW;
                        can.height = pieceW;
              ctx.drawImage(nImg,pieceW*i,pieceW*j,pieceW,pieceW,0,0,1080,1440);
              arr1.push(ctx);
            }
           poixl.push(arr1);
        }
        c();
    }
    //每个小方块内共有256个像素,将每个像素点的灰度值,存入一个数组。
    function c(){
         let arr = [];
        for(let i = 0 ; i < poixl.length ; i++){
            let arr1 = [];
            for(let n = 0; n < poixl[i].length ; n++){
                let arr2 = [];
                for(let j = 0 ; j < pieceW ; j++ ){
                    for(let k = 0 ; k < pieceW ; k++ ){
                            let data = poixl[i][n].getImageData(j,k,1,1).data;
                            // 计算灰度值
                            arr2.push((data[0]+data[1]+data[2])/3);      
                    }
                }
                arr1.push(arr2);
            }
            arr.push(arr1);
        }
       
        d(arr);
    }
    
   // 第三步,计算该数组的平均值,并用1-6之间的一个整数来表示。
   // 计算平均值
   function d(arr){
           let ava = []; 
           for(let i = 0 ; i < arr.length ; i++){
               for(let j = 0 ; j < arr[i].length ; j++){
                   let val = 0;
                   for(let k = 0; k < arr[i][j].length ; k++){
                        val += arr[i][j][k];
                   }
                    arr[i][j] = val/arr[i].length;
                    arr[i][j] = e(arr[i][j]);
               }
           }
          f(arr);
   }
   // 用1-6直接的整数表示
   function e(average){
            if(average>=0 && average <= 42){
                return 1;
            }else if(average>42 && average <= 85){
                return 2;
            }else if(average>85 && average <= 127){
                return 3;
            }else if(average>127 && average <= 169){
                return 4;
            }else if(average>169 && average <= 211){
                return 5;
            }else{
                return 6;
            }
   }
   
   function f(arr){
       console.log(arr);
       console.time("time");
       let count = 0 ;
       for(let i = 0 ; i < arr.length ; i ++){
           for(let j = 0 ; j < arr[i].length ; j++){
               switch(arr[i][j]){
                   case 1: context.drawImage(imgArr[0],i*pieceW,j*pieceW,pieceW,pieceW);break;
                   case 2: context.drawImage(imgArr[1],i*pieceW,j*pieceW,pieceW,pieceW);break;
                   case 3: context.drawImage(imgArr[2],i*pieceW,j*pieceW,pieceW,pieceW);break;
                   case 4: context.drawImage(imgArr[3],i*pieceW,j*pieceW,pieceW,pieceW);break;
                   case 5: context.drawImage(imgArr[4],i*pieceW,j*pieceW,pieceW,pieceW);break;
                   case 6: context.drawImage(imgArr[5],i*pieceW,j*pieceW,pieceW,pieceW);break;
               }
           }           
       }
        body.appendChild(canvas);
        console.timeEnd("time");
   }
   原图

//切割小方块的边长

pieceW = 16;

pieceW = 12;

pieceW = 8;

注意:本文是使用js完成  ,在使用getImageData方法获取像素的时候可能会遇到图片源的问题 ,只需要将图片和js代码放在同一服务器下或者放在可以跨越访问的服务器上,我用了hbuilder的内置web服务器避免了图片源污染的问题 。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值