在 android 上实时模糊仍然是一个障碍。以下是一些可行机制之间的综合比较:
StackBlur(已在Onur 的名字fastBlur 的答案中列出):
外观(半径 20 处):
生成每个BitmapDrawable 的记录时间(毫秒):
I/(10266): Total time taken: 35
I/(10266): Total time taken: 54
I/(10266): Total time taken: 48
I/(10266): Total time taken: 36
I/(10266): Total time taken: 48
I/(10266): Total time taken: 39
I/(10266): Total time taken: 49
I/(10266): Total time taken: 50
I/(10266): Total time taken: 35
I/(10266): Total time taken: 47
平均 => ~ 44.1 毫秒 => 每秒 22 个可绘制对象
渲染脚本:
ScriptIntrinsicBlur 提供始终如一的快速模糊。它使用支持库提供的 api 8 及更高版本。
它的样子(在半径 20 处):
生成每个BitmapDrawable 的记录时间(毫秒):
I/(9342): Total time taken: 14
I/(9342): Total time taken: 16
I/(9342): Total time taken: 13
I/(9342): Total time taken: 28
I/(9342): Total time taken: 14
I/(9342): Total time taken: 12
I/(9342): Total time taken: 14
I/(9342): Total time taken: 19
I/(9342): Total time taken: 13
I/(9342): Total time taken: 13
平均 => ~ 15.6 毫秒 => 每秒 64 个可绘制对象
RenderScript(半径 = 3)+ 缩放(20%):
这是获得体面(?)但快速模糊的另一种方式。我们所做的是将位图缩放到其大小的一小部分——比如 20%——并将模糊算法应用于缩小版本。完成后,我们将位图缩放到其原始大小。结果不如在原版上使用模糊算法,但还算过得去。另请注意,半径值不应太高,否则生成的位图将难以辨认。
它的样子:
生成每个BitmapDrawable的记录时间(毫秒):
I/(11631): Total time taken: 5
I/(11631): Total time taken: 19
I/(11631): Total time taken: 3
I/(11631): Total time taken: 7
I/(11631): Total time taken: 7
I/(11631): Total time taken: 5
I/(11631): Total time taken: 7
I/(11631): Total time taken: 17
I/(11631): Total time taken: 5
I/(11631): Total time taken: 4
平均 => ~ 7.9 毫秒 => 每秒 126 个可绘制对象
StackBlur(半径 = 3)+ 缩放(20%):
与上述#3 相同的概念。将尺寸减小到 20% 并在缩放的位图上应用 stackblur。
I/(12690): Total time taken: 4
I/(12690): Total time taken: 20
I/(12690): Total time taken: 4
I/(12690): Total time taken: 4
I/(12690): Total time taken: 5
I/(12690): Total time taken: 5
I/(12690): Total time taken: 4
I/(12690): Total time taken: 21
I/(12690): Total time taken: 3
I/(12690): Total time taken: 4
平均 => ~ 7.4 毫秒 => 每秒 135 个可绘制对象
在 Nex4 上进行的测试。
位图大小 - 200px x 200px
另一个提示:方法buildDrawingCache() 和getDrawingCache() 本身需要很长时间。另一种方法是使用您需要模糊的视图尺寸创建位图:
Bitmap toDrawOn = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
// Create a canvas - assign `toDrawOn` as an offscreen bitmap to it
Canvas holdingCanvas = new Canvas(toDrawOn);
// Now, let the view draw itself on this canvas
yourView.draw(holdingCanvas);
视图现在绘制在toDrawOn 上,您可以随意使用它。
根据我的经验,这比生成和访问视图的绘图缓存要快得多。
如果您在实施上述 4 种方法中的任何一种时需要帮助,请在 cmets 中告诉我。
请记住,上面的 GIF 已被缩小等等。如果您想查看原始屏幕捕获 (mp4) 文件,请查看此Link。