如何使用位图绘制路径?

时间:2011-08-10 03:48:28

标签: android android-canvas drawing2d

我有一个小绘图应用程序,并希望使用“复杂”形状作为画笔,即明星。 使用简单的画笔绘制已经可以使用此代码:

remotePath.reset();
remotePath.moveTo(start_x, start_y);

float dx = Math.abs(end_x - start_x);
float dy = Math.abs(end_y - start_y);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        remotePath.quadTo(start_x, start_y, (end_x + start_x) / 2, (end_y + start_y) / 2);
}

remotePath.lineTo(end_x, end_y);
// commit the path to our offscreen
mCanvas.drawPath(remotePath, remotePaint);
// kill this so we don't double draw
remotePath.reset();
invalidate();

我基本上想要使用这个位图的相同功能:

Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.brush_star);

我的解决方案目前正在使用一个点(坐标)列表来绘制位图。该解决方案的问题在于它仅在给定点处绘制位图,导致每个绘制的位图之间存在间隙。我宁愿想要画一条平滑的线,同时用简单的画笔画画,两者之间没有任何间隙。

位图绘制的当前代码:

        protected void onDraw(Canvas canvas) {

        // Make canvas white
        canvas.drawColor(Color.WHITE);

        // Paintable area
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);

        for (Point point : points) {
            canvas.drawBitmap(complexBrush, point.x, point.y, p);
        }
    }

最好的方法是什么? 谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

我用这个 Point的课程:

public class Point  implements Serializable {
float x, y;
float dx, dy;
}

绘制对象:

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
paint.setAntiAlias(true);

在画布上画画:

private void drawCanvas(Canvas canvas, List<Point> pts){
    if (pts.size() > 1){
        Path path = new Path();
        final int SMOOTH_VAL = 6;
        for(int i = pts.size() - 2; i < pts.size(); i++){
            if(i >= 0){
                Point point = pts.get(i);

                if(i == 0){
                    Point next = pts.get(i + 1);
                    point.dx = ((next.x - point.x) / SMOOTH_VAL);
                    point.dy = ((next.y - point.y) / SMOOTH_VAL);
                }
                else if(i == pts.size() - 1){
                    Point prev = pts.get(i - 1);
                    point.dx = ((point.x - prev.x) / SMOOTH_VAL);
                    point.dy = ((point.y - prev.y) / SMOOTH_VAL);
                }
                else{
                    Point next = pts.get(i + 1);
                    Point prev = pts.get(i - 1);
                    point.dx = ((next.x - prev.x) / SMOOTH_VAL);
                    point.dy = ((next.y - prev.y) / SMOOTH_VAL);
                }
            }
        }

        boolean first = true;
        for(int i = 0; i < pts.size(); i++){
            Point point = pts.get(i);
            if(first){
                first = false;
                path.moveTo(point.x, point.y);
            }
            else{
                Point prev = pts.get(i - 1);
                path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x - point.dx, point.y - point.dy, point.x, point.y);
            }
        }
        canvas.drawPath(path, paint);
    } else {
        if (pts.size() == 1) {
            Point point = pts.get(0);
            canvas.drawCircle(point.x, point.y, 2, paint);
        }
    }
}

在位图画布上绘图:

private void drawBitmap(Bitmap bmp, List<Point> pts) {
    Canvas c = new Canvas(bmp);
    drawCanvas(c, pts);
}