2013-02-20 101 views
31

我一直在尋找過去三天內置的,硬件加速的android模糊位圖的方法。我偶然發現了一些縮小位圖並將其擴展的解決方法,但是這種方法產生的低質量結果不適合我的圖像識別要求。我還讀到,使用着色器或JNI實現卷積是一個很好的方法,但我不相信Android框架中沒有內置的解決方案來實現這個共同的目的。目前我已經用Java編寫了一個自編寫的卷積實現,但速度很慢。我的問題是:Android:快速位圖模糊?

  • 真正的Android框架沒有內置的解決方案
  • 如果沒有的話:在仍然合理的實施和維護複雜度下加速卷積的最有效方法是什麼?我們應該使用JNI,着色器還是完全不同的東西?

回答

68

我終於找到一個合適的解決方案:

  • RenderScript允許執行那些被透明地縮放到執行裝置上的所有可用核重計算。我得出結論,就性能和實現複雜性的合理平衡而言,這是比JNI或着色器更好的方法。
  • 由於API級別17,有API可用的ScriptIntrinsicBlur類。這正是我一直在尋找的,即高水平的硬件加速高斯模糊實現。
  • ScriptIntrinsicBlur現在是支持Froyo及以上(API> 8)的android支持庫(v8)的一部分。有關如何使用它的一些基本技巧,support RenderScript library上的Android開發人員博客帖子。

但是,關於ScriptIntrinsicBlur類的文檔非常少見,我花了一些時間來計算正確的調用參數。對於bluring名爲photo普通ARGB_8888 -typed位圖,在這裏,他們是:

final RenderScript rs = RenderScript.create(myAndroidContext); 
final Allocation input = Allocation.createFromBitmap(rs, photo, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 
final Allocation output = Allocation.createTyped(rs, input.getType()); 
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 
script.setRadius(myBlurRadius /* e.g. 3.f */); 
script.setInput(input); 
script.forEach(output); 
output.copyTo(photo); 
+2

@ thV0ID:很好的答案。有什麼辦法可以使它向後兼容,也可以在ICS中工作? – 2013-07-13 07:03:29

+0

@BhaveshPatadiya:您可以使用RenderScript實現快速卷積並使用高斯內核。在RenderScript中實現卷積的一個例子可以在這裏找到:http://stackoverflow.com/a/10257994/1444073 – theV0ID 2013-07-31 19:39:05

+3

RS現在是兼容性庫的一部分,renderscript-v8.jar – Gabor 2013-09-24 15:44:23

11

可能是最苛刻的要求是活的模糊,這意味着你活的模糊效果的觀點變化。在這種情況下,模糊不應該花費超過10秒左右(使一些遊戲室進入16ms/60fps)看起來很平滑。即使不是那麼高端的設備(galaxy s3,甚至更慢),也可以通過正確的設置來實現這種效果。

這裏是如何按重要性提高性能:

  1. 使用縮小的圖片: 這降低了像素極大模糊。當你想要一個真實的模糊圖像時,它也適用於你。圖像加載和內存消耗也大幅降低。

  2. 使用Renderscript ScriptIntrinsicBlur - 2014年Android中可能沒有更好/更快的解決方案。我經常看到的一個錯誤是,Renderscript上下文沒有被重用,但每次使用blur模式時都會創建。請注意,在Nexus 5上,RenderScript.create(this);需要20ms左右,所以您想避免這種情況。

  3. 重用位圖:不要創建不必要的實例並始終使用相同的實例。當你需要真正快速的模糊時,垃圾收集扮演着重要角色(收集一些位圖需要10-20毫秒的時間)。也裁剪和模糊只有你需要的東西。

  4. 對於活動模糊,可能是因爲上下文切換,它不可能在另一個線程中模糊(即使使用線程池),只有主線程足夠快以保持視圖更新及時,線程我看到滯後100-300ms

更多的提示,請參閱我在這裏的其他職位https://stackoverflow.com/a/23119957/774398

BTW。我在這個應用程序做了一個簡單的生活模糊:github,Playstore

+0

關於#2,我看不出它有這樣的好品質模糊(見這裏:http://stackoverflow.com/q/36447630/878126)。另外,你真的暗示st Renderscript對象將保留整個應用程序生命週期,而不需要調用「destroy()」? – 2016-04-06 09:58:13

+0

嗨,我想你已經在你的文章中發現了質量差的錯誤(我想說我不能重新編制你的錯誤輸出)。對於第二點:如果你模糊了,當然不會破壞上下文。請記住,創建上下文是昂貴的 – for3st 2016-04-06 13:02:18

+0

質量差 - 我不確定原因(因爲我使用了其他示例和教程代碼),但我使用了「createTyped」,現在它可以工作。如果你可以在那裏寫下我爲什麼會遇到這些問題,那就太好了。關於「銷燬上下文」,我正在談論RenderScript.create。如果我在應用中的很多地方模糊圖像,應該沒問題,永遠不要銷燬它,對吧?另外,它用於爭論的是什麼語境? – 2016-04-06 14:04:19