Кажется, что проблема должна быть решена с помощью RenderScript. Однако кажется, что он поддерживает только размытие растрового изображения, поэтому нам может потребоваться разрезать растровое изображение до размытия. Обращаясь к this answer о быстром размытии изображения, я смог добиться удивительно хорошей производительности на планшете Nexus 10.
Код следующее (примечание: это черновой вариант, я играл с ним только в течение 30 минут):
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);
}
}
}
Результат:
Хотя я опасался, что создание Bitmap
в onDraw
вызовет большие задержки, в действии только с этой областью размытия изображения движется довольно плавно.
Вы что-то пробовали? –
@ChintanRathod: Я пробовал рисовать по изображению. Когда я скольжу пальцем по изображению, он рисует изображение. Я хочу сделать так, чтобы каким-то образом изменить параметры объекта Paint, чтобы при перемещении пальца вместо рисования просто размыли часть изображения. –
Вы можете сделать это, но для этого вам нужно разместить 2 растровых изображения над другими. Фронт будет оригинальным. Заднее изображение будет размытым. Попробуйте найти «стереть изображение при касании». Это обеспечит вам стирание верхнего изображения, чтобы вывести заднее изображение, и пользователь чувствует, что изображение становится размытым. :) –