zoukankan      html  css  js  c++  java
  • 谈谈文字图片像素化

      先来看个简单的demo-> 像素粒子化

      demo是基于3d旋转算法+像素粒子化实现的,尚有一些bug和性能问题,我们不做深究。本篇主要谈谈如何将文字和图片的像素粒子化。针对这个demo,也就是如何实现如下两个图片的转换。

           

      

      无论文字还是图片,本篇所讲都是针对画布,这点要清楚。如果是文字,用fillText方法将文字写到画布上,如果是图片,则用drawImage方法将图片画到画布上。然后通过getImageData方法获取像素,进行判断,从而取得想要的坐标。不了解getImageData的具体可参考:getImageData

      如何获取想要的像素点坐标?一般情况下我们可以根据像素点rgba中的a值(透明度)进行判断。

      法1:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img =  document.getElementById('img1');
    ctx.drawImage(img, 0, 0);
    var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    var length = data.length;
    var textPoint = [];
    for (var i = 0, wl = canvas.width * 4; i < length; i += 4) {
      if (data[i + 3]) {  // 根据透明度判断
        var x = (i % wl) / 4;
        var y = parseInt(i / wl)
        textPoint.push([x, y]);
      }
    }
    

      法2:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img =  document.getElementById('img1');
    ctx.drawImage(img, 0, 0);
    var textPoint = [];
    var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    for(var i = 0; i < imgData.width; i++)
      for(var j = 0; j < imgData.height; j++) {
        var index = (i + j * imgData.width) * 4 + 3;
        if(imgData.data[index]) {
          textPoint.push([i, j]);
        }
      }  
    

      fillText:

    ctx.font = "bold 12px serif"
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillStyle = 'red';
    ctx.fillText('慧', 0, 0);
    

      

     

    1、文字像素粒子化

    • 小文字 * textSize 法

      这是一种比较常用的方法。首先在画布上用fillText写文字,但是写的文字像素要小,一般选择笔画宽2~3个像素,甚至一个像素点。然后通过getImageData获取的data值再进行判断计算获得坐标,其实就是获得文字所组成像素的相对位置。然后将获得的坐标乘以一个常数,就是粒子的大小(实际粒子大小可能会小于textSize以产生粒子间的间隙),这里把它称为textSize,乘以常数后得到一个新的坐标即为粒子化后粒子的坐标。这样在每帧渲染时只需操作新的坐标即可,得到的是相对来说扩大textSize倍的字。

      demo:06wj demo

      优点:可任意文字代码扩展性强

      缺点:字体选择少;效果不直观,需调整文字大小和textSize值调整效果

      总结:适用于粒子大的demo,一般文字宽度1~3个像素

    • 大文字 + 舍弃部分像素点法

      这种方法也比较常见。首先在画布上用fillText写好文字,但是文字一定要大,跟最终出现的效果文字差不多大小,然后也是通过getImageData操作像素点,但是这里要舍弃部分像素点,因为并发的粒子太多进程会卡掉。舍弃多少因情况而异,一般舍弃的数量和粒子的大小成正比,因为舍弃的粒子需要留下的粒子通过扩大来占位。

      怎么舍弃?方法参数根据需要的效果随意,例举一二:

         

      demo:W·Axes 粒子化Demo2     岑安 demo

      优点:可任意文字代码扩展性强;最终大小效果直观

      缺点:字体选择少;需要靠舍弃像素的多少调整粒子大小

      总结:适用于粒子小的demo

    • 其他

      直接用大文字,因为像素点太多太密,而且如果不舍弃的话粒子只能以0.5为半径,体验十分差,在粒子化中基本不考虑。倒是在别的方面可能有用处,花丛效果文字就用到了,因为每帧不用重绘,所以渲染也不会卡。

      直接用小文字那就根本不用考虑了。

    2、图片像素粒子化

      demo采用的就是图片像素粒子化。先把图片draw到画布上,接下去的操作就和文字一样了。这里提一点,在本地操作时,getImageData方法报错:

      提示跨域操作data,实际上就是跨域操作图片了。解决方法就是把代码和图片都放到服务器环境下(相同域名)。因为本地测试用的图片是文件夹内的,js跨域限制是不能获取非同一域名下的数据的, 而本地的位置是没有域名的,所以浏览器都认为你是跨域,导致报错。或者check  Javascript - getImageData after fillRect and drawImage

      图片操作的结果其实就和小文字*textSize类似(有人可能会说可以用大图片,剔除部分像素点,但是大图片体积大加载不易,并且剔除麻烦,我这里就不考虑了),不同的是图片能操作各种炫酷的文字,除了文字之外图片还能操作别的需要的形状。图片的像素点也有要求,像素点太多后续渲染压力会很大浏览器会崩溃,最好像素删减后控制在1000以内,一般图片20*20可取图上所有像素点;不考虑直接用大图片,浏览器会崩溃,所以只能小图片 * size。

      demo:岑安 JX官网首页3D粒子效果

      优点:不仅限于文字,适用范围广; 文字字体选择多样,效果好看

      缺点:获取图片不方便;可扩展性不强每个demo要重新获取图片

    3、其他

      粒子化除了文字和图片外,还有很多,比如数组模拟,这里就不加介绍了,具体请check:事情没有想象中那么难--JX官网首页3D粒子效果 

  • 相关阅读:
    Linux:删除程序
    Linux:目录操作
    Linux:加载硬盘
    mysql:查询结果添加序列号
    mysql:结果集去重
    mysql:字符串转换为日期类型
    MVC:上传文件时限制文件类型
    WebApi:WebApi的Self Host模式
    WebApi:过滤器的种类
    几种知名开源富文本编辑器记录和对比(仅供参考)
  • 原文地址:https://www.cnblogs.com/lessfish/p/4251174.html
Copyright © 2011-2022 走看看