Blur on touch. Android application

丶灬走出姿态 提交于 2019-12-18 06:49:40

问题


I am trying to make an application in which the part of the image user touched on the android app gets blurred.

Requirement is like, I should be able to take a snap and then slide over my finger over the points which I need to blur out. Is there any easy way for it. Can I somehow use transparent paint with opacity to accomplish it?

Thanks


回答1:


Seems the issue should be solved using RenderScript. However, seems that it supports only bitmap blur, so we might need to cut bitmap before blurring. Referring to this answer about fast image blur, I was able to achieve surprisingly good performance on Nexus 10 tablet.

The code is following (note: it's draft version, I've played with it only 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);
        }
    }
}

Result is:

Although I was afraid that creating Bitmap in onDraw will cause big lags, in activity with only this view blur area moves quite smoothly.



来源:https://stackoverflow.com/questions/18188079/blur-on-touch-android-application

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!