谈谈文字图片像素化

  先来看个简单的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粒子效果 

转载于:https://www.cnblogs.com/lessfish/p/4251174.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值