Touch blur. Android App
I'm trying to make an application in which the image user touches the part of the Android application becomes blurred
The requirement is that I should be able to take a pat and then slide my finger over the fuzzy point I need. Is there a simple way? Can I use opaque transparent paint to complete it in some way?
thank you
resolvent:
It seems that the problem should be solved by renderscript. However, it seems that it only supports bitmap blur, so we may need to cut the bitmap before blur. For fast image blur, refer to this answer. I have achieved surprisingly good performance on the nexus 10 tablet
The code is as follows (Note: I only played the draft version for 30 minutes):
public class BlurTouchImageView extends View {
private static final int BLUR_RADIUS = 20;
// TODO: resources should be used
private static final int BLUR_SIDE = 300;
private RenderScript mBlurScript = null;
private ScriptIntrinsicBlur mIntrinsicScript = null;
private Bitmap mBitmap = null;
private Bitmap mBlurredBitmap = null;
private float mX = -1;
private float mY = -1;
public BlurTouchImageView(final Context context) {
super(context);
init();
}
public BlurTouchImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public BlurTouchImageView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* Inits our view internal members
*/
private void init() {
mBlurScript = RenderScript.create(getContext());
mIntrinsicScript = ScriptIntrinsicBlur.create(mBlurScript, Element.U8_4(mBlurScript));
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.gimg);
mBlurredBitmap = Bitmap.createBitmap(BLUR_SIDE, BLUR_SIDE, mBitmap.getConfig());
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
boolean retval = false;
mX = event.getX();
mY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
retval = true;
invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mX = -1;
mY = - 1;
retval = true;
invalidate();
break;
default:
// nothing to do here
break;
}
return retval;
}
@Override
protected void onDraw(final Canvas canvas) {
// Blur bitmap if it's touched
canvas.drawBitmap(mBitmap, 0, 0, null);
if (mX > 0 && mY > 0) {
// Yeah, it will slooow down drawing, but how else we can prepare needed part of bitmap?
final Bitmap blurSource = Bitmap.createBitmap(mBitmap, (int) mX - BLUR_SIDE / 2, (int) mY - BLUR_SIDE / 2, BLUR_SIDE, BLUR_SIDE);
final Allocation inAlloc = Allocation.createFromBitmap(mBlurScript, blurSource, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
final Allocation outAlloc = Allocation.createFromBitmap(mBlurScript, mBlurredBitmap);
mIntrinsicScript.seTradius(BLUR_RADIUS);
mIntrinsicScript.setInput(inAlloc);
mIntrinsicScript.forEach(outAlloc);
outAlloc.copyTo(mBlurredBitmap);
canvas.drawBitmap(mBlurredBitmap, (int)mX - BLUR_SIDE / 2, (int)mY - BLUR_SIDE / 2, null);
}
}
}
The result is:
Although I'm worried that creating a bitmap in OnDraw will cause a lot of lag, in activities with only this view, the fuzzy area moves quite smoothly