最近在做业务需求时,需要实现对图片的液化功能,类似于美图秀秀的瘦脸功能。这已经不仅是图片缩放、拖动、剪裁这类对图片整体的操作了,而是需要对图片的像素进行一系列的计算和修改,那么该怎么实现这个功能呢?
分别测试了半径为 50 100 200 400 情况的差别:
半径 | Math.floor | 位运算 |
---|---|---|
50 | 50ms | 10ms |
100 | 100ms | 30ms |
200 | 400ms | 120ms |
400 | 1400ms | 400ms |
此外,因为涉及到频繁读取 ImageData 这种超大位数的数据,所以也有不少小细节也是能够起到性能优化的作用(虽然体感上不是太明显)
- 位操作符 ~~ 替代 Math.floor
- 缓存中间结果
- ImageData 大数组 只创建需要修改的部分
- bit 计算通过+4 而不是直接计算
具体的实现都可以参考 demo 实现。
总结
在实现液化的过程中,各种研究和实现的整个过程还是花费了很多精力,有以下几个体感:
- 经典的理论永不会过时
- 学好数学,真的很重要
- 数学公式可能是极简的美,但是工程实现要考虑更多的实际问题(比如取整、边界处理)
声明:文章系转载,原文链接