Available from API 17, ScriptIntrinsicBlur - is a Intrinsic Gausian blur filter, pplies a gaussian blur of the specified radius to all elements of an allocation, blurring image work become easier. Today, in this post, I will present a sample project show how to create blur bitmap with these 2 Object, I also provide a SeekBar to change the blurred amount. See this DEMO VIDEO first for ouput:
Note: The following example code is developed for API17 and higher. I have decided against using the v8 support library for RenderScript.
Firstly, make a simple layout for project's main activity contains a SeekBar and an ImageView like this:
Note: like develope doc say, radius of Blur (a float value) supported from 0 to 25.0. So, please set max value is 25 for SeekBar.
The following code snippets can be used create a bitmap blur effect in Android using RenderScript API:
private Bitmap createBlurBitmap(Bitmap src, float r) {
if (r <= 0) {
r = 0.1f;
} else if (r > 25) {
r = 25.0f;
}
Bitmap bitmap = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
RenderScript renderScript = RenderScript.create(this);
Allocation blurInput = Allocation.createFromBitmap(renderScript, src);
Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
blur.setInput(blurInput);
blur.setRadius(r);
blur.forEach(blurOutput);
blurOutput.copyTo(bitmap);
renderScript.destroy();
return bitmap;
}
To increase/decrease the opacity by SeekBar, provide a OnSeekBarChangeListener method and override nested follow methods:
private OnSeekBarChangeListener onSeekBarChanged() {
return new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textRadius.setText("Blur radius: " + progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
float radius = (float) MainActivity.this.seekBar.getProgress();
imageView.setImageBitmap(createBlurBitmap(bitmap, radius));
}
};
}
Recommended set Blur Bitmap for ImageView in onStopTrackingTouch() to avoid lagging in weak memory/chip devices.Set handling event for SeekBar, locate views, we now have full code for main activity:
package info.devexchanges.blurimage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textRadius;
private ImageView imageView;
private SeekBar seekBar;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textRadius = (TextView) findViewById(R.id.txt_radius);
imageView = (ImageView) findViewById(R.id.image);
seekBar = (SeekBar) findViewById(R.id.blur_radius);
//decode a drawable resource to Bitmap
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ao_dai);
imageView.setImageBitmap(bitmap);
textRadius.setText("Blur radius: 0");
//handling seek bar event
seekBar.setOnSeekBarChangeListener(onSeekBarChanged());
}
private OnSeekBarChangeListener onSeekBarChanged() {
return new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
textRadius.setText("Blur radius: " + progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
float radius = (float) MainActivity.this.seekBar.getProgress();
imageView.setImageBitmap(createBlurBitmap(bitmap, radius));
}
};
}
private Bitmap createBlurBitmap(Bitmap src, float r) {
if (r <= 0) {
r = 0.1f;
} else if (r > 25) {
r = 25.0f;
}
Bitmap bitmap = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
RenderScript renderScript = RenderScript.create(this);
Allocation blurInput = Allocation.createFromBitmap(renderScript, src);
Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
blur.setInput(blurInput);
blur.setRadius(r);
blur.forEach(blurOutput);
blurOutput.copyTo(bitmap);
renderScript.destroy();
return bitmap;
}
}
After running app, we have this output:Because of this ScriptIntrinsicBlur only added from API 17, so your project must define in app/build.gradle file about min-sdk:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "info.devexchanges.blurimage"
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
You may also use support v8 library to use this method, more details, see this post in Android Developers blog, I haven't mentioned here. Full code of this project now available on Github, you can clicked below button to view. Thank for reading, subcribe my blog to see newest tutorials!
