How to make custom brush for canvas in android?

后端 未结 2 661
慢半拍i
慢半拍i 2020-12-07 10:07

In my canvas application i want to use custom brushes like brushes in attached image.so please somebody help me fast how can i make custom brushes like attached image?

相关标签:
2条回答
  • 2020-12-07 10:36

    As you can clearly see, no trivial shader effects / rectangles / circles can accomplish this. Images / Bitmaps are used.

    So simply repeatedly draw Bitmaps using canvas.drawBitmap. You draw the same Bitmap again and again while the finger moves.

    For adding a custom color you can add a simple filter.

    An Example

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-07 10:44

    Though it is too late i want to share something. This might help someone. Various brush techniques are discussed in the following link with JavaScript code for HTML canvas. All you have to do is convert JavaScript code to your expected one. It is pretty simple to covert JavaScript Canvas code to Android Canvas code.

    Exploring canvas drawing techniques

    I have converted "Multiple lines" technique to Java code for android; You can check the following android view code.

    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);
    }
    

    }

    0 讨论(0)
提交回复
热议问题