サーチ…


前書き

RenderScriptは、高性能なグラフィックレンダリングと生の計算コードを記述できるスクリプト言語です。これは、システムが後で実行できるプロセッサのネイティブコードにコンパイルするために重要なコードを書く手段を提供します。これは、CPU、マルチコアCPU、さらにはGPUでもかまいません。最終的には、開発者がすぐに利用できない多くの要素に依存しますが、内部プラットフォームコンパイラがサポートするアーキテクチャにも依存します。

入門

RenderScriptは、Android上での高性能並列計算を可能にするフレームワークです。あなたが書いたスクリプトは、使用可能な全てのプロセッサ(例えば、CPU、GPUなど)にわたって並列に実行され、スケジューリングされ実行される方法ではなく、達成したいタスクに集中することができます。

スクリプトはC99ベースの言語で書かれています(C99はCプログラミング言語標準の古いバージョンです)。各スクリプトごとに、Javaコード内のRenderScriptと簡単にやり取りできるJavaクラスが作成されます。

プロジェクトの設定

Androidフレームワークライブラリまたはサポートライブラリを使用して、アプリケーション内のRenderScriptにアクセスするには2つの方法があります。 APIレベル11より前にデバイスをターゲティングしたくない場合でも、さまざまなデバイス間でデバイスの互換性が保証されるため、サポートライブラリの実装を常に使用する必要があります。サポートライブラリの実装を使用するには、少なくともビルドツールバージョン18.1.0を使用する必要があります。

次に、アプリケーションのbuild.gradleファイルをセットアップします。

android {
    compileSdkVersion 24
    buildToolsVersion '24.0.1'

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 24

        renderscriptTargetApi 18
        renderscriptSupportModeEnabled true
    }
}
  • renderscriptTargetApi :必要なすべてのRenderScript機能を提供する最も早いAPIレベルに設定する必要があります。
  • renderscriptSupportModeEnabled :サポートライブラリRenderScriptの実装を使用できるようにします。

RenderScriptのしくみ

典型的なRenderScriptは、カーネルと関数という2つの要素で構成されています。関数はちょうどそのようなものです。関数は入力を受け取り、その入力で何かを行い、出力を返します。カーネルは、RenderScriptの真のパワーが得られる場所です。

カーネルは、 Allocation内のすべての要素に対して実行される関数です。 Allocationは、 Bitmapbyte配列のようなデータをRenderScriptに渡すために使用することができ、カーネルから結果を得るためにも使用されます。カーネルは、1つのAllocationを入力として、もう1つを出力として、または1つのAllocation内のデータを変更することができます。

あなたは一つのカーネルを書くことができますが、Gaussian Image Blurのような一般的な操作を実行するために使用できる多くの定義済みのカーネルもあります。

すべてのRenderScriptファイルについて既に述べたように、クラスはそれと対話するために生成されます。これらのクラスは常に接頭辞ScriptC_ RenderScriptファイルの名前で始まります。たとえば、RenderScriptファイルがexampleと呼ばれるexample 、生成されたJavaクラスはScriptC_exampleと呼ばれScriptC_example 。事前に定義されたすべてのスクリプトは接頭辞Script ScriptIntrinsicBlurます。たとえば、Gaussian Image Blur ScriptはScriptIntrinsicBlurです。

あなたの最初のRenderScriptを書く

次の例は、GitHubの例に基づいています。これは、画像の彩度を変更することによって、基本的な画像操作を実行します。 ここでソースコードを見つけて、それを自分で試してみたいと思っているなら、それをチェックすることができます。結果は以下のようになります。

デモ画像

RenderScriptボイラープレート

RenderScriptファイルはプロジェクトのsrc/main/rsフォルダにあります。各ファイルにはファイル拡張子.rsあり、先頭に2つの#pragma文が含まれている必要があります。

#pragma version(1)
#pragma rs java_package_name(your.package.name)
  • #pragma version(1) :使用しているRenderScriptのバージョンを設定できます。現在、バージョン1のみが存在します。

  • #pragma rs java_package_name(your.package.name) :この特定のRenderScriptと対話するために生成されたJavaクラスのパッケージ名を設定するために使用できます。

別の#pragmaがあります。通常、各RenderScriptファイルに設定する必要があり、浮動小数点精度を設定するために使用されます。浮動小数点精度は3つの異なるレベルに設定できます。

  • #pragma rs_fp_full :これは最高精度の最も厳しい設定で、何も指定しない場合のデフォルト値です。高い浮動小数点精度が必要な場合は、これを使用する必要があります。
  • #pragma rs_fp_relaxed :これは高い浮動小数点精度を保証するものではありませんが、一部のアーキテクチャではスクリプトを高速化できるような最適化が可能です。
  • #pragma rs_fp_imprecise :これにより、より精度が低くなり、浮動小数点精度がスクリプトに本当に関係しない場合に使用する必要があります。

ほとんどのスクリプトは#pragma rs_fp_relaxed使うことができ#pragma rs_fp_relaxedただし、浮動小数点精度が本当に必要な場合を除きます。

グローバル変数

Cコードのように、グローバル変数や定数を定義することができます:

const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};

float saturationLevel = 0.0f;

変数gMonoMultの型はfloat3です。つまり、3つの浮動小数点数からなるベクトルです。他のfloat変数saturationValueは定数ではないため、実行時に好きな値に設定することができます。あなたのカーネルや関数でこのような変数を使うことができるので、RenderScriptに入力を与えたり、出力を受け取ったりする別の方法です。定数ではない変数のそれぞれに対して、関連付けられたJavaクラスでgetterおよびsetterメソッドが生成されます。

カーネル

しかし、今ではカーネルを実装することができます。この例では、イメージの彩度を変更するためにカーネルで使用された数学について説明するつもりはなく、カーネルを実装する方法とその使用方法に焦点を当てます。この章の最後では、このカーネルのコードが実際に何をしているのかを簡単に説明します。

一般的なカーネル

最初にソースコードを見てみましょう:

uchar4 __attribute__((kernel)) saturation(uchar4 in) {
    float4 f4 = rsUnpackColor8888(in);
    float3 dotVector = dot(f4.rgb, gMonoMult);
    float3 newColor = mix(dotVector, f4.rgb, saturationLevel);
    return rsPackColorTo8888(newColor);
}

ご覧のとおり、通常のC関数のように見えますが、戻り値の型とメソッド名の間には__attribute__((kernel))があります。これは、このメソッドがカーネルであることをRenderScriptに知らせるものです。あなたが気付くかもしれない別のことは、このメソッドがuchar4パラメータを受け入れ、別のuchar4値を返すことです。 uchar4は、前の章で説明したfloat3変数のように、ベクトルです。それは0から255までの範囲のバイト値である4つのuchar値を含んでucharます。

これらの個々の値にはさまざまな方法でアクセスできます。たとえば、 in.rはピクセルの赤いチャネルに対応するバイトを返します。それぞれのピクセルは赤の場合はr 、緑の場合はg 、青の場合はb 、青の場合はa 、アルファの場合はbの4つの値で構成されているため、 uchar4を使用します。 RenderScriptでは、ベクトルから任意の数の値を取り出して、別のベクトルを作成することもできます。たとえば、 in.rgbは、アルファ値のないピクセルの赤、緑、青の部分だけを含むuchar3値を返します。

実行時に、RenderScriptはイメージの各ピクセルに対してこのKernelメソッドを呼び出します。その理由は、戻り値とパラメータがただ1つのuchar4値にすぎないuchar4です。 RenderScriptは、使用可能なすべてのプロセッサでこれらの呼び出しの多くを並列に実行するため、RenderScriptは非常に強力です。これは、スレッディングやスレッドの安全性について心配する必要がないことを意味します。各ピクセルに何をしたいのかを実装するだけで、RenderScriptは残りの部分を処理します。

Javaでカーネルを呼び出すときは、2つのAllocation変数を指定します.1つは入力データを含み、もう1つは出力を受け取ります。あなたのカーネルメソッドは、入力Allocation各値に対して呼び出され、その結果を出力Allocation書き込みます。

RenderScriptランタイムAPIメソッド

上のカーネルでは、いくつかの方法が使用されています。 RenderScriptには多くのメソッドが用意されており、RenderScriptを使用して実行するほとんどのものにとって不可欠です。それらの中には、 sin()ような数学演算を行うメソッドと、別の値に従って2つの値を混合するmix()ようなヘルパーメソッドがあります。しかし、ベクトル、四元数、および行列を扱うときには、より複雑な操作のためのメソッドもあります。

公式のRenderScriptランタイムAPIリファレンスは、特定のメソッドの詳細を知りたい場合や、行列の内積を計算するなどの一般的な操作を実行する特定のメソッドを探している場合に、最適なリソースです。このドキュメントはここで見つけることができます。

カーネルの実装

さて、このカーネルが何をしているのかを見てみましょう。カーネルの最初の行は次のとおりです:

float4 f4 = rsUnpackColor8888(in);

最初の行は、 uchar4値をfloat4値に変換するuchar4メソッドrsUnpackColor8888()を呼び出します。各色チャネルは、範囲に変換さ0.0f - 1.0f場合0.0fバイトの値に対応する0及び1.0f255 。これの主な目的は、このカーネルのすべての数学をもっと簡単にすることです。

float3 dotVector = dot(f4.rgb, gMonoMult);

この次の行は、組み込みメソッドdot()を使用して、2つのベクトルの内積を計算します。 gMonoMultは上のいくつかの章を定義した定数です。両方のベクトルはドット積を計算するのに同じ長さでなければならないので、ピクセルのアルファチャンネルではなくカラーチャンネルに影響を与えたいので、 float3ベクトルを得るために.rgbを使用します。赤色、緑色および青色のチャネルを含む。ドットプロダクトがどのように動作するかを学校から覚えている人々は、ドットプロダクトがベクトルではなく1つの値を返す必要があることをすぐに認識します。上記のコードでは、結果をfloat3ベクタに代入しています。これもRenderScriptの機能です。 1次元の数値をベクトルに代入すると、ベクトルのすべての要素がこの値に設定されます。たとえば、次のスニペットは、 float3ベクトルの3つの値のそれぞれに2.0fを割り当てます。

float3 example = 2.0f;

上のドット積の結果は、上記のfloat3ベクトルの各要素に割り当てられます。

今度は、グローバル変数saturationLevelを使ってイメージのsaturationLevelを変更する部分があります:

float3 newColor = mix(dotVector, f4.rgb, saturationLevel);

これは組み込みのメソッドmix()を使用して元の色と上記で作成したドット積ベクトルを混合します。どのように混合されるかは、グローバルsaturationLevel変数によって決まります。したがって、 saturationLevel0.0f場合、結果のカラーは元のカラー値の一部を持たず、結果として白黒またはグレーアウトされたイメージになるdotVector内の値のみで構成されます。 1.0fの値を1.0fすると、結果の色は元の色の値で完全に構成され、 1.0fと元の色が増えて明るく鮮やかになります。

return rsPackColorTo8888(newColor);

これはカーネルの最後の部分です。 rsPackColorTo8888()は、 float3ベクトルをuchar4値に変換して戻します。結果のバイト値は0〜255の範囲にクランプされるため、 1.0fより大きい浮動小数点値は255のバイト値となり、 0.0より小さい値は0バイト値になり0

それがカーネルの実装全体です。今では残っている部分は1つだけです:Javaでカーネルを呼び出す方法。

JavaでRenderScriptを呼び出す

基本

各RenderScriptファイルについて既に説明したように、Javaクラスが生成され、スクリプトと対話できます。これらのファイルには、 ScriptC_という接頭辞の後にRenderScriptファイルの名前が続きます。これらのクラスのインスタンスを作成するには、 RenderScriptクラスのインスタンスが必要です。

final RenderScript renderScript = RenderScript.create(context);

静的メソッドcreate()を使用して、 ContextからRenderScriptインスタンスを作成できます。その後、スクリプト用に生成されたJavaクラスをインスタンス化できます。 RenderScriptファイルsaturation.rsを呼び出した場合、そのクラスはScriptC_saturationと呼ばれScriptC_saturation

final ScriptC_saturation script = new ScriptC_saturation(renderScript);

このクラスでは、飽和レベルを設定してカーネルを呼び出すことができます。 saturationLevel変数のために生成されたsetterは、接頭辞set_後に変数の名前が続きます。

script.set_saturationLevel(1.0f);

また、現在設定されている彩度レベルを取得できるget_という接頭辞が付いたゲッターもあります。

float saturationLevel = script.get_saturationLevel();

RenderScriptで定義したカーネルの先頭には、 forEach_カーネルメソッドの名前が続きます。我々が書いたカーネルは、入力Allocationと出力Allocationをそのパラメータとして期待している:

script.forEach_saturation(inputAllocation, outputAllocation);

入力Allocationは入力イメージが含まれている必要があり、 forEach_saturationメソッドの終了後に出力割り当てに変更されたイメージデータが含まれます。

Allocationインスタンスを取得すると、メソッドcopyFrom()およびcopyTo()を使用して、これらのAllocationsとの間でデータをコピーできます。たとえば、新しい画像を `Call by Allocation 'という入力にコピーすることができます:

inputAllocation.copyFrom(inputBitmap);

出力Allocation copyTo()を呼び出すことによって結果イメージを取得するのと同じ方法です。

outputAllocation.copyTo(outputBitmap);

割り当てインスタンスの作成

Allocationを作成する方法はたくさんあります。あなたが持っている一度Allocationあなたがそれらからとに新しいデータをコピーすることができインスタンスをAllocationscopyTo()copyFrom()のようには、上記で説明しますが、最初にそれらを作成するために、あなたは正確に作業しているデータの種類を知っている必要があります。入力のAllocationから始めましょう:

静的メソッドcreateFromBitmap()を使用して、 Bitmapから入力Allocationを素早く作成することができます。

final Allocation inputAllocation = Allocation.createFromBitmap(renderScript, image);

この例では、入力イメージは決して変更されないため、入力のAllocation再度変更する必要はありません。 saturationLevelが変更されて新しい出力Bitmap作成されるたびに、再利用することができます。

出力Allocation作成はもう少し複雑です。まず、 Typeと呼ばれるものを作成する必要があります。 Typeは、どのような種類のデータを扱っているかをAllocationために使用されます。通常、 Type.Builderクラスを使用して適切なTypeを素早く作成します。最初にコードを見てみましょう:

final Type outputType = new Type.Builder(renderScript, Element.RGBA_8888(renderScript))
        .setX(inputBitmap.getWidth())
        .setY(inputBitmap.getHeight())
        .create();

私たちは、通常の32ビット(つまり、4バイト)のBitmapを4つのカラーチャネルで処理しています。そのため、 Typeを作成するにはElement.RGBA_8888を選択しています。その後、我々は、メソッド使用setX()setY() 、入力画像と同じサイズに出力画像の幅と高さを設定します。次に、 create()メソッドは、指定したパラメータでTypeを作成します。

我々は正しいたらType 、私たちは、出力を作成することができますAllocation静的メソッドとcreateTyped()

final Allocation outputAllocation = Allocation.createTyped(renderScript, outputType);

今我々はほぼ完了している。出力Allocationからのデータをコピーできる出力Bitmapも必要です。これを行うには、静的メソッドcreateBitmap()を使用して、入力Bitmapと同じサイズと構成で新しい空のBitmapを作成します。

final Bitmap outputBitmap = Bitmap.createBitmap(
        inputBitmap.getWidth(),
        inputBitmap.getHeight(),
        inputBitmap.getConfig()
);

そしてそれで私たちはRenderScriptを実行するためのすべてのパズルを持っています。

完全な例

ここでは、これらをまとめて1つの例として示します。

// Create the RenderScript instance
final RenderScript renderScript = RenderScript.create(context);

// Create the input Allocation 
final Allocation inputAllocation = Allocation.createFromBitmap(renderScript, inputBitmap);

// Create the output Type.
final Type outputType = new Type.Builder(renderScript, Element.RGBA_8888(renderScript))
        .setX(inputBitmap.getWidth())
        .setY(inputBitmap.getHeight())
        .create();

// And use the Type to create am output Allocation
final Allocation outputAllocation = Allocation.createTyped(renderScript, outputType);

// Create an empty output Bitmap from the input Bitmap
final Bitmap outputBitmap = Bitmap.createBitmap(
        inputBitmap.getWidth(),
        inputBitmap.getHeight(),
        inputBitmap.getConfig()
);

// Create an instance of our script
final ScriptC_saturation script = new ScriptC_saturation(renderScript);

// Set the saturation level
script.set_saturationLevel(2.0f);

// Execute the Kernel
script.forEach_saturation(inputAllocation, outputAllocation);

// Copy the result data to the output Bitmap
outputAllocation.copyTo(outputBitmap);

// Display the result Bitmap somewhere
someImageView.setImageBitmap(outputBitmap);

結論

この紹介では、簡単な画像操作のために独自のRenderScriptカーネルを作成するように設定する必要があります。しかし、あなたが覚えておかなければならないことがいくつかあります:

  • RenderScriptはアプリケーションプロジェクトでのみ機能します 。現在、RenderScriptファイルはライブラリプロジェクトの一部にすることはできません。
  • メモリに注意してください:RenderScriptは非常に高速ですが、メモリを大量に消費することもあります。いつでもRenderScriptインスタンスは2つ以上存在してはいけません。また、できるだけ再利用する必要があります。通常、 Allocationインスタンスを一度作成するだけで、将来的にそれらを再利用することができます。出力Bitmapsやスクリプトインスタンスも同様です。できるだけ再利用してください。
  • バックグラウンドでの作業 :やはりRenderScriptは非常に速いですが、決して瞬時にはできません。カーネル、特に複雑なカーネルは、 AsyncTaskなどのUIスレッドから実行する必要があります。しかし、ほとんどの場合、メモリリークを心配する必要はありません。すべてのRenderScript関連クラスはアプリケーションContextのみを使用するため、メモリリークは発生しません。しかし、あなたは、あなたが自分自身を使用しているViewActivityまたはContextインスタンスを漏らすような通常のものについては、まだ心配する必要があります!
  • 組み込みのものを使う :画像ぼかし、ブレンド、変換、サイズ変更などのタスクを実行する定義済みのスクリプトが多数あります。また、カーネルを実装するのに役立つ方法がたくさんあります。あなたが何かしたいのであれば、あなたがやろうとしていることを既に行っているスクリプトやメソッドがある可能性があります。車輪を再構築しないでください。

実際のコードですぐに使い始めるには、このチュートリアルで説明した例を実装したGitHubプロジェクトの例をご覧ください。 ここでプロジェクトを見つけることができます。 RenderScriptを楽しんでください!

画像をぼかす

この例では、Renderscript APIを使用して画像をぼかし(ビットマップを使用)する方法を示します。この例では、使用ScriptInstrinsicBlurアンドロイドのrenderScript API(API> = 17)によって提供されます。

public class BlurProcessor {
    
    private RenderScript rs;
    private Allocation inAllocation;
    private Allocation outAllocation;
    private int width;
    private int height;

    private ScriptIntrinsicBlur blurScript;

    public BlurProcessor(RenderScript rs) {
        this.rs = rs;
    }
    
    public void initialize(int width, int height) {
        blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        blurScript.setRadius(7f); // Set blur radius. 25 is max

        if (outAllocation != null) {
            outAllocation.destroy();
            outAllocation = null;
        }
        
        // Bitmap must have ARGB_8888 config for this type
        Type bitmapType = new Type.Builder(rs, Element.RGBA_8888(rs))
            .setX(width)
            .setY(height)
            .setMipmaps(false) // We are using MipmapControl.MIPMAP_NONE
            .create();
        
        // Create output allocation
        outAllocation = Allocation.createTyped(rs, bitmapType);

        // Create input allocation with same type as output allocation
        inAllocation = Allocation.createTyped(rs, bitmapType);
    }

    public void release() {
        
        if (blurScript != null) {
            blurScript.destroy();
            blurScript = null;
        }
    
        if (inAllocation != null) {
            inAllocation.destroy();
            inAllocation = null;
        }

        if (outAllocation != null) {
            outAllocation.destroy();
            outAllocation = null;
        }
    }

    public Bitmap process(Bitmap bitmap, boolean createNewBitmap) {
        if (bitmap.getWidth() != width || bitmap.getHeight() != height) {
            // Throw error if required
            return null;
        }
        
        // Copy data from bitmap to input allocations
        inAllocation.copyFrom(bitmap);

        // Set input for blur script
        blurScript.setInput(inAllocation);

        // process and set data to the output allocation
        blurScript.forEach(outAllocation);
        
        if (createNewBitmap) {
            Bitmap returnVal = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            outAllocation.copyTo(returnVal);
            return returnVal;
        }

        outAllocation.copyTo(bitmap);
        return bitmap;
    }
}    

各スクリプトにはデータを処理するカーネルがあり、一般的にforEachメソッドを介して呼び出されます。

public class BlurActivity extends AppCompatActivity {
    private BlurProcessor blurProcessor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // setup layout and other stuff

        
        blurProcessor = new BlurProcessor(Renderscript.create(getApplicationContext()));
    }

    private void loadImage(String path) {
        // Load image to bitmap
        Bitmap bitmap = loadBitmapFromPath(path);
        
        // Initialize processor for this bitmap
        blurProcessor.release();
        blurProcessor.initialize(bitmap.getWidth(), bitmap.getHeight());
        
        // Blur image
        Bitmap blurImage = blurProcessor.process(bitmap, true); // Use newBitamp as false if you don't want to create a new bitmap
    }
}

これでここでの例が結論づけられました。バックグラウンドスレッドで処理することをお勧めします。

ビューをぼかす

BlurBitmapTask.java

public class BlurBitmapTask extends AsyncTask<Bitmap, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private final RenderScript renderScript;

    private boolean shouldRecycleSource = false;

    public BlurBitmapTask(@NonNull Context context, @NonNull ImageView imageView) {
        // Use a WeakReference to ensure
        // the ImageView can be garbage collected
        imageViewReference = new WeakReference<>(imageView);
        renderScript = RenderScript.create(context);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(Bitmap... params) {
        Bitmap bitmap = params[0];
        return blurBitmap(bitmap);
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap == null || isCancelled()) {
            return;
        }

        final ImageView imageView = imageViewReference.get();
        if (imageView == null) {
            return;
        }

        imageView.setImageBitmap(bitmap);
    }

    public Bitmap blurBitmap(Bitmap bitmap) {
        // https://plus.google.com/+MarioViviani/posts/fhuzYkji9zz

        //Let's create an empty bitmap with the same size of the bitmap we want to blur
        Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
                Bitmap.Config.ARGB_8888);

        //Instantiate a new Renderscript


        //Create an Intrinsic Blur Script using the Renderscript
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));

        //Create the in/out Allocations with the Renderscript and the in/out bitmaps
        Allocation allIn = Allocation.createFromBitmap(renderScript, bitmap);
        Allocation allOut = Allocation.createFromBitmap(renderScript, outBitmap);

        //Set the radius of the blur
        blurScript.setRadius(25.f);

        //Perform the Renderscript
        blurScript.setInput(allIn);
        blurScript.forEach(allOut);

        //Copy the final bitmap created by the out Allocation to the outBitmap
        allOut.copyTo(outBitmap);

        // recycle the original bitmap
        // nope, we are using the original bitmap as well :/
        if (shouldRecycleSource) {
            bitmap.recycle();
        }

        //After finishing everything, we destroy the Renderscript.
        renderScript.destroy();

        return outBitmap;
    }

    public boolean isShouldRecycleSource() {
        return shouldRecycleSource;
    }

    public void setShouldRecycleSource(boolean shouldRecycleSource) {
        this.shouldRecycleSource = shouldRecycleSource;
    }
}

使用法:

ImageView imageViewOverlayOnViewToBeBlurred
        .setImageDrawable(ContextCompat.getDrawable(this, android.R.color.transparent));
View viewToBeBlurred.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW);
viewToBeBlurred.setDrawingCacheEnabled(true);
BlurBitmapTask blurBitmapTask = new BlurBitmapTask(this, imageViewOverlayOnViewToBeBlurred);
blurBitmapTask.execute(Bitmap.createBitmap(viewToBeBlurred.getDrawingCache()));
viewToBeBlurred.setDrawingCacheEnabled(false);


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow