
How to develop BlurImageView?
Discovering Material Design gave me a chance to play with animations and image effects. While watching Chiu Ki Chan presentation “Fun with Android Shaders and Filters” I got an idea to create the “focus loss” effect, well known from the DSLR cameras – blurring the image with simultaneous enlarging it. The effect was used instead of default Material Design image tinting pattern. I achieveed it by extendeding ImageView and using RenderScript to blur the original Bitmap.
RenderScript rs = RenderScript.create(getContext());
Allocation allocIn = Allocation.createFromBitmap(rs, original);
Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
rs, Element.U8_4(rs));
blur.setInput(allocIn);
blur.setRadius(radius);
blur.forEach(allocOut);
allocOut.copyTo(bitmap);
rs.destroy();
Of course it’s SDK >= 17 so for older devices you need alternative method. I used “Stack Blur Algorithm” by Mario Klingemann which works fast on my Samsung Galaxy S2.
I wanted to blur image gradually so I correlated radius with percentage of ImageView visibility and every time radius changed new blurred Bitmap was generated inside onDraw method. Unfortunately it was really inefficient and looked like a slideshow, not like smooth animation. Second idea was drawing original Bitmap with changing transparency on most blurred Bitmap. As easy as setting proper alpha in your paint:
originalPaint.setAlpha(128); //value from 0 (max. blurred) to 255 (sharpest)
canvas.drawBitmap(blurBitmap, resizeMatrix, blurPaint);
canvas.drawBitmap(originalBitmap, resizeMatrix, originalPaint);
New solution turned out to be quite fast and efficient, you can check how it works below. Whole BlurImageView class code is available on gist https://gist.github.com/bartektrail/3067b3f29ab4c958a985
How to use it?
Add BlurImageView to your layout.
<pl.snowdog.material.view.BlurImageView android:id="@+id/blur_iv" android:src="@drawable/mountain_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop"/>
Set in code focus value. It’s between 0 and 1.0f where 0 is sharp and 1.0 is fully blurred image.
public class TestBlurActivity extends Activity {
@InjectView(R.id.blur_iv)
BlurImageView mBlurImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_blur);
ButterKnife.inject(this);
mBlurImageView.setFocus(1.0f); // max. blur
}
}
You can add setFocus method to onScrollChanged or other user interaction but it’s more complex. To keep this post simple, I created sample code snippet code for you, that shows sharp->blurred->sharp animation:
public class TestBlurActivity extends Activity {
@InjectView(R.id.blur_iv)
BlurImageView mBlurImageView;
float focus = 0;
boolean asc = true;
Handler animationHandler = new Handler();
Runnable animationRunnable = new Runnable() {
@Override
public void run() {
if (focus > 1)
asc = false;
if (focus < 0)
asc = true;
if (asc) {
focus += 0.05f;
} else {
focus -= 0.05f;
}
mPhotoView.setFocus(focus);
animationHandler.postDelayed(animationRunnable, 100);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_blur);
ButterKnife.inject(this);
animationHandler.postDelayed(animationRunnable, 100); /start animation
}
}
Next posts
In the next post we will show you how to implement couple of Material Design features in Pre-Lollipop devices. Stay tuned :)