我正在创建一个绘图应用程序,我希望用户可以使用的画笔具有以下效果:
目前,为了实现这种效果,我正在绘制 5 个单独的路径,每个路径具有相同的 X 值但 Y 偏移量很小,并且每个路径都有一个 BlurMaskFilter。这是 PaintBrush 类的代码:
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);
这段代码可以工作,但是,在禁用硬件加速的情况下,我的绘图活动对性能造成了巨大的(并且不可接受的)影响;它的延迟非常明显,尤其是当路径变长时。我的问题是:有没有一种方法可以在不使用硬件加速的情况下提高性能,足以减少延迟?如果没有,有没有办法以与硬件加速兼容的方式模拟同样的效果?