Android BlurMaskFilter问题

mwecs4sa  于 2022-12-25  发布在  Android
关注(0)|答案(2)|浏览(107)

我正在创建一个绘图应用程序,我希望用户可以使用的画笔中有一个具有以下效果:

目前,为了达到这个效果,我绘制了5个独立的路径,每个路径都有相同的X值,但Y偏移量较小,每个路径都有一个BlurMaskFilter。

public PaintBrush(int initColor, int initSize) {
    strokeRadius = ((10 * initSize) + 20) / 2;
    currentColor = initColor
    setupPaths();
}

private void setupPaths(){
    paths = new Path[5];
    paints = new Paint[5];
    for (int i = 0; i < 5; i++){
        paths[i] = new Path();
        Paint curPaint =  new Paint();
        curPaint.setColor(currentColor);
        curPaint.setAntiAlias(true);
        curPaint.setDither(true);
        curPaint.setStyle(Paint.Style.STROKE);
        curPaint.setStrokeJoin(Paint.Join.ROUND);
        curPaint.setStrokeCap(Paint.Cap.ROUND);
        paints[i] = curPaint;
    }
    Paint paint1 = paints[0];
    paint1.setStrokeWidth(strokeRadius / 3);
    paint1.setMaskFilter(new BlurMaskFilter(Math.max(strokeRadius / 5, 1), BlurMaskFilter.Blur.NORMAL));
    Paint paint2 = paints[1];
    paint2.setStrokeWidth(strokeRadius / 6);
    paint2.setMaskFilter(new BlurMaskFilter(Math.max(strokeRadius / 7, 1), BlurMaskFilter.Blur.NORMAL));
    Paint paint3 = paints[2];
    paint3.setStrokeWidth(strokeRadius / 5);
    paint3.setMaskFilter(new BlurMaskFilter(Math.max(strokeRadius / 7, 1), BlurMaskFilter.Blur.NORMAL));
    Paint paint4 = paints[3];
    paint4.setStrokeWidth(strokeRadius / 3);
    paint4.setMaskFilter(new BlurMaskFilter(Math.max(strokeRadius / 4, 1), BlurMaskFilter.Blur.NORMAL));
    Paint paint5 = paints[4];
    paint5.setStrokeWidth(strokeRadius / 4);
    paint5.setMaskFilter(new BlurMaskFilter(Math.max(strokeRadius / 4, 1), BlurMaskFilter.Blur.NORMAL));
}

public void drawBrush(Canvas canvas){
    for (int i = 0; i < 5; i++) {
        canvas.drawPath(paths[i], paints[i]);
    }
}


public void startStroke(float x, float y){
    paths[0].moveTo(x, y - (strokeRadius * 4 / 6));
    paths[1].moveTo(x, y - (strokeRadius / 3));
    paths[2].moveTo(x, y - (strokeRadius / 8));
    paths[3].moveTo(x, y + (strokeRadius / 3));
    paths[4].moveTo(x, y + (strokeRadius * 3 / 4));
    prevX = x;
    prevY = y;
}

public void moveStroke(float x, float y){
    float dx = Math.abs(x - prevX);
    float dy = Math.abs(y - prevY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        paths[0].quadTo(prevX, prevY - (strokeRadius * 4 / 6), (x + prevX) / 2, ((y + prevY) / 2) - (strokeRadius * 4 / 6));
        paths[1].quadTo(prevX, prevY - (strokeRadius / 3), (x + prevX) / 2, ((y + prevY) / 2) - (strokeRadius / 3));
        paths[2].quadTo(prevX, prevY - (strokeRadius / 8), (x + prevX) / 2, ((y + prevY) / 2) - (strokeRadius / 8));
        paths[3].quadTo(prevX, prevY + (strokeRadius / 3), (x + prevX) / 2, ((y + prevY) / 2) + (strokeRadius / 3));
        paths[4].quadTo(prevX, prevY + (strokeRadius * 3 / 4), (x + prevX) / 2, ((y + prevY) / 2) + (strokeRadius * 3 / 4));
    }
    prevX = x;
    prevY = y;
}

public void endStroke(Canvas canvas){
    drawBrush(canvas);
    paths[0].reset();
    paths[1].reset();
    paths[2].reset();
    paths[3].reset();
    paths[4].reset();
}

以及自定义视图的代码:

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(drawingCanvas, 0, 0, canvasPaint);
    currentBrush.drawBrush(canvas);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (!activity.isPaused()) {
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                currentBrush.startStroke(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                currentBrush.moveStroke(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                currentBrush.endStroke(touchX, touchY, drawingCanvas);
                break;
            default:
                return false;
        }
        invalidate();
    }
    return true;
}

我知道BlurMaskFilter与硬件加速不兼容,所以在我的主活动中,我有以下代码:

drawingView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

这段代码可以正常工作,但是,在禁用硬件加速的情况下,我的绘图活动受到了巨大的(不可接受的)性能影响;它有一个非常明显的滞后,特别是当路径变长的时候。我的问题是:有没有一种方法可以在不使用硬件加速的情况下提高性能,足以减少延迟?2如果没有,有没有一种方法可以用与硬件加速兼容的方式来模拟相同的效果?

efzxgjgh

efzxgjgh1#

保留一个整个屏幕大小的位图,保留一个手指移动过的所有点的列表,对从上一个触摸点到最后一个触摸点的距离设置一个最小的阈值,你实际上是把绘图运动分解成一个点列表。
现在,每当手指移动时,找到自上次处理触摸事件以来发生更改的区域的边框,清除此矩形,然后使用drawPath仅重绘列表中位于此矩形中的线条。

相关问题