Android
RenderScript
サーチ…
前書き
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
は、 Bitmap
やbyte
配列のようなデータを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.0f
に255
。これの主な目的は、このカーネルのすべての数学をもっと簡単にすることです。
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
変数によって決まります。したがって、 saturationLevel
が0.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
あなたがそれらからとに新しいデータをコピーすることができインスタンスをAllocations
とcopyTo()
と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
のみを使用するため、メモリリークは発生しません。しかし、あなたは、あなたが自分自身を使用しているView
、Activity
または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);