如何在android中为画布制作自定义画笔?

时间:2011-12-08 09:37:02

标签: android

在我的画布应用程序中,我想在附加图像中使用自定义画笔,例如画笔。所以请有人帮我快速如何制作附加图像的自定义画笔?

在我的应用程序中,我使用以下代码制作了虚线:

 mPaint.setPathEffect(new DashPathEffect(new float[] { 8, 8 }, 0));

使用以下代码获得Blur和Emboss效果:

 mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);

 mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);

enter image description here

2 个答案:

答案 0 :(得分:20)

正如您可以清楚地看到的,没有琐碎的着色器效果/矩形/圆圈可以实现此目的。 使用图像/位图。

所以简单地使用canvas.drawBitmap重复绘制位图。在手指移动时,您可以反复绘制相同的位图。

要添加自定义颜色,您可以添加一个简单的过滤器。

示例

public class CanvasBrushDrawing extends View {
    private Bitmap mBitmapBrush;
    private Vector2 mBitmapBrushDimensions;

    private List<Vector2> mPositions = new ArrayList<Vector2>(100);

    private static final class Vector2 {
        public Vector2(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public final float x;
        public final float y;
    }

    public CanvasBrushDrawing(Context context) {
        super(context);

// load your brush here
        mBitmapBrush = BitmapFactory.decodeResource(context.getResources(), R.drawable.splatter_brush);
        mBitmapBrushDimensions = new Vector2(mBitmapBrush.getWidth(), mBitmapBrush.getHeight());

        setBackgroundColor(0xffffffff);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (Vector2 pos : mPositions) {
            canvas.drawBitmap(mBitmapBrush, pos.x, pos.y, null);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_MOVE:
            final float posX = event.getX();
            final float posY = event.getY();
            mPositions.add(new Vector2(posX - mBitmapBrushDimensions.x / 2, posY - mBitmapBrushDimensions.y / 2));
            invalidate();
        }

        return true;
    }
}

答案 1 :(得分:4)

尽管为时已晚,我想分享一些东西。这可能会帮助某人。在下面的链接中,针对HTML canvas的JavaScript代码讨论了各种画笔技术。您要做的就是将JavaScript代码转换为您期望的代码。将JavaScript Canvas代码转换为Android Canvas代码非常简单。

Exploring canvas drawing techniques

我已将“多行”技术转换为android的Java代码;您可以检查以下android视图代码。

public class MultipleLines extends View {

private Bitmap bitmap;
private Canvas canvas;

private Paint mPaint;

public MultipleLines(Context context) {
    super(context);
    init();
}

private void init(){
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFFFF0000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(1);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    canvas = new Canvas(bitmap);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
    }
    return true;
}

private boolean isDrawing;
private List<PointF> points = new ArrayList<>();

private void touch_start(float touchX, float touchY) {
    isDrawing = true;
    points.add(new PointF(touchX, touchY));

    canvas.save();
}
private void touch_move(float touchX, float touchY) {
    if (!isDrawing) return;

    canvas.drawColor(Color.TRANSPARENT);

    points.add(new PointF(touchX, touchY));

    stroke(offsetPoints(-10));
    stroke(offsetPoints(-5));
    stroke(points);
    stroke(offsetPoints(5));
    stroke(offsetPoints(10));
}

private void touch_up() {
    isDrawing = false;
    points.clear();
    canvas.restore();
}

private List<PointF> offsetPoints(float val) {
    List<PointF> offsetPoints = new ArrayList<>();
    for (int i = 0; i < points.size(); i++) {
        PointF point = points.get(i);
        offsetPoints.add(new PointF(point.x + val, point.y + val));
    }
    return offsetPoints;
}

private void stroke(List<PointF> points) {
    PointF p1 = points.get(0);
    PointF p2 = points.get(1);

    Path path = new Path();
    path.moveTo(p1.x, p1.y);

    for (int i = 1; i < points.size(); i++) {
        // we pick the point between pi+1 & pi+2 as the
        // end point and p1 as our control point
        PointF midPoint = midPointBtw(p1, p2);
        path.quadTo(p1.x, p1.y, midPoint.x, midPoint.y);
        p1 = points.get(i);
        if(i+1 < points.size()) p2 = points.get(i+1);
    }
    // Draw last line as a straight line while
    // we wait for the next point to be able to calculate
    // the bezier control point
    path.lineTo(p1.x, p1.y);

    canvas.drawPath(path,mPaint);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(bitmap, 0, 0, null);
}

private PointF midPointBtw(PointF p1, PointF p2) {
    return new PointF(p1.x + (p2.x - p1.x) / 2.0f, p1.y + (p2.y - p1.y) / 2.0f);
}

}