33

私は過去3日間、Androidでビットマップをぼかす組み込みのハードウェアアクセラレーションによる方法を探していました。ビットマップを縮小して再度スケールアップするなどの特定の回避策に遭遇しましたが、この方法では低品質の結果が生成され、画像認識の要件には適していませんでした。また、シェーダーまたはJNIを使​​用して畳み込みを実装することは良い方法であることも読みましたが、この非常に一般的な目的のためにAndroidフレームワークに組み込みのソリューションがないことは信じられません。現在、私はJavaでの自作の畳み込み実装に行き着きましたが、それはぎこちなく遅いです。私の質問は:

  • Androidフレームワークに組み込みのソリューションは本当にありませんか?
  • 何もない場合:実装と保守が依然として合理的な複雑さで畳み込みを加速する最も効率的な方法は何ですか?JNI、シェーダー、またはまったく異なるものを使用しますか?
4

2 に答える 2

73

私はついに適切な解決策を見つけました:

  • RenderScriptを使用すると、実行デバイスで使用可能なすべてのコアに対して透過的にスケーリングされる大量の計算を実装できます。パフォーマンスと実装の複雑さの合理的なバランスに関して、これはJNIやシェーダーよりも優れたアプローチであるという結論に達しました。
  • APIレベル17以降、APIから利用できるScriptIntrinsicBlurクラスがあります。これはまさに私が探していたものです。つまり、高レベルのハードウェアアクセラレーションによるガウスぼかしの実装です。
  • ScriptIntrinsicBlurは、Froyo以降(API> 8)をサポートするAndroidサポートライブラリ(v8)の一部になりました。サポートRenderScriptライブラリに関するAndroid開発者のブログ投稿には、その使用方法に関するいくつかの基本的なヒントがあります。

ただし、ScriptIntrinsicBlurクラスに関するドキュメントは非常にまれであり、正しい呼び出し引数を理解するためにもう少し時間を費やしました。、という名前の通常の型のARGB_8888ビットマップをぼかすためphotoに、ここにそれらがあります:

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 );
于 2013-02-20T20:10:04.577 に答える
13

おそらく最も要求の厳しい要件はライブ ブラーです。この状況では、ぼかしが滑らかに見えるのに 10 ミリ秒程度 (16 ミリ秒/60 fps にいくらかの余裕を持たせるため) かかることはありません。それほどハイエンドではないデバイス (galaxy s3 およびさらに低速) でも、適切な設定でこの効果を実現できます。

重要度の降順でパフォーマンスを向上させる方法は次のとおりです。

  1. 縮小された画像を使用する: これにより、ピクセルが大幅に減少してぼやけます。また、実際のぼやけた画像が必要な場合にも機能します。また、画像の読み込みとメモリ消費が大幅に削減されます。

  2. Renderscript ScriptIntrinsicBlur を使用してください - 2014 年の時点で、Android にはおそらくより優れた/高速なソリューションはありません。私がよく目にする間違いの 1 つは、Renderscript コンテキストが再利用されず、ぼかしアルゴリズムが使用されるたびに作成されることです。RenderScript.create(this);Nexus 5 では約 20 ミリ秒かかるので、これは避けたいと思います。

  3. ビットマップの再利用: 不要なインスタンスを作成せず、常に同じインスタンスを使用します。非常に高速なぼかしが必要な場合、ガベージ コレクションが重要な役割を果たします (一部のビットマップの収集に 10 ~ 20 ミリ秒かかります)。また、必要なものだけをトリミングしてぼかします。

  4. ライブ ブラーの場合、おそらくコンテキストの切り替えが原因で、別のスレッドでブラーを実行することはできません (スレッドプールを使用しても)。

その他のヒントについては、こちらの他の投稿を参照してください https://stackoverflow.com/a/23119957/774398

ところで。このアプリで簡単なライブブラーを行いました: github , Playstore

于 2014-04-27T22:42:42.393 に答える