I am new to Android and I am developing a sample project on drawing lines. I want to draw a curved or elevated line connecting two points (x1,y1 and x2,y2). I tried canvas.drawArc() method, but the RectF values inside the drawArc method is just the x,y center points of circle. It is giving me an arc between my two points. But I want a curved line exactly connecting my two points. Can somebody help me? Thanks in advance.
Declare this method inside onDraw method:
private void drawOvalAndArrow(Canvas canvas){
Paint circlePaint = new Paint();
circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
circlePaint.setAntiAlias(true);
circlePaint.setStrokeWidth(2);
circlePaint.setColor(Color.CYAN);
float centerWidth = canvas.getWidth()/2; //get center x of display
float centerHeight = canvas.getHeight()/2; //get center y of display
float circleRadius = 20; //set radius
float circleDistance = 200; //set distance between both circles
//draw circles
canvas.drawCircle(centerWidth, centerHeight, circleRadius, circlePaint);
canvas.drawCircle(centerWidth+circleDistance, centerHeight, circleRadius, circlePaint);
//to draw an arrow, just lines needed, so style is only STROKE
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setColor(Color.RED);
//create a path to draw on
Path arrowPath = new Path();
//create an invisible oval. the oval is for "behind the scenes" ,to set the path´
//area. Imagine this is an egg behind your circles. the circles are in the middle of this egg
final RectF arrowOval = new RectF();
arrowOval.set(centerWidth,
centerHeight-80,
centerWidth + circleDistance,
centerHeight+80);
//add the oval to path
arrowPath.addArc(arrowOval,-180,180);
//draw path on canvas
canvas.drawPath(arrowPath, circlePaint);
//draw arrowhead on path start
arrowPath.moveTo(centerWidth,centerHeight ); //move to the center of first circle
arrowPath.lineTo(centerWidth-circleRadius, centerHeight-circleRadius);//draw the first arrowhead line to the left
arrowPath.moveTo(centerWidth,centerHeight );//move back to the center
arrowPath.lineTo(centerWidth+circleRadius, centerHeight-circleRadius);//draw the next arrowhead line to the right
//same as above on path end
arrowPath.moveTo(centerWidth+circleDistance,centerHeight );
arrowPath.lineTo((centerWidth+circleDistance)-circleRadius, centerHeight-circleRadius);
arrowPath.moveTo(centerWidth+circleDistance,centerHeight );
arrowPath.lineTo((centerWidth+circleDistance)+circleRadius, centerHeight-circleRadius);
//draw the path
canvas.drawPath(arrowPath,circlePaint);
}
Also this will find the two sides of the screen (Landscape mode) and will draw a perfect curve across the screen
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
PointF mPoint1 = new PointF(w/1.2F, h/1.2F);
PointF mPoint2 = new PointF(w/24, h/1.2F);
Path myPath1 = new Path();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
myPath1 = drawCurve(canvas, paint, mPoint1, mPoint2);
canvas.drawPath(myPath1, paint);
}
private Path drawCurve(Canvas canvas, Paint paint, PointF mPointa, PointF mPointb) {
Path myPath = new Path();
myPath.moveTo(63*w/64, h/10);
myPath.quadTo(mPointa.x, mPointa.y, mPointb.x, mPointb.y);
return myPath;
}
Useful references on painting in android:
How to draw Arcs in Android using canvas?
Basic Painting with Views
It might not be what u want, but take a look at http://developer.android.com/reference/android/graphics/Path.html more precisely at moveTo, lineTo, quadTo and cubicTo. (The last 2 methods will draw bezier curves, either quadratic or cubic. If u don't know what those are, take a look at http://en.wikipedia.org/wiki/B%C3%A9zier_curve You only need to understand the parameters of the funcion, not the math behind it). For your purpose you can do like this:
Path mPath;
Paint paint;
mPath = new Path();
mPath.moveTo(x1, y1);
mPath.cubicTo(anchor1_x, anchor1_y, anchor2_x, anchor2_y, x2, y2); /*the anchors you want, the curve will tend to reach these anchor points; look at the wikipedia article to understand more */
paint = new Paint();
paint.setColor(0xFFFFFFFF);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(width); //the width you want
canvas.drawPath(mPath, paint);
Related
Whant to draw as in this image
for that would use as in the link ShapeDrawable Drawing multiple shapes with ShapeDrawable in xml with Android but don't know how to make the line curve
---------------------edit-----------------------------------
based on #Bojan Kseneman answer tried with the following code
PointF pt1l = new PointF(canvas.getWidth()/2+40, (float)newPosY-canvas.getWidth()/40);//canvas.getWidth()/40
PointF pt2l = new PointF(canvas.getWidth()/2+40, (float)newPosY+canvas.getWidth()/40);
PointF midl = new PointF(canvas.getWidth()/2+30, (float)newPosY+canvas.getWidth()/40);
PointF pt1r = new PointF(canvas.getWidth()/2-40, (float)newPosY-canvas.getWidth()/40);
PointF pt2r = new PointF(canvas.getWidth()/2-40, (float)newPosY+canvas.getWidth()/40);
PointF midr = new PointF(canvas.getWidth()/2-30, (float)newPosY+(canvas.getWidth()/40)/2);
Path pathLeft = new Path();
//pathLeft.setFillType(Path.FillType.EVEN_ODD);
pathLeft.moveTo(pt1l.x,pt1l.y);
pathLeft.quadTo(midl.x,midl.y,pt2l.x,pt2l.y);
Path pathRight = new Path();
//pathRight.setFillType(Path.FillType.EVEN_ODD);
pathRight.moveTo(pt1r.x,pt1r.y);
pathRight.quadTo(midr.x,midr.y,pt2r.x,pt2r.y);
Paint curveLineR = new Paint();
curveLineR.setColor(Color.GREEN);
Paint curveLineL = new Paint();
curveLineL.setColor(Color.GREEN);
Paint circle = new Paint();
circle.setColor(Color.GREEN);
canvas.drawPath(pathLeft, curveLineL);
canvas.drawPath(pathRight, curveLineR);
//canvas.drawCircle(canvas.getWidth()/2,canvas.getHeight()/2,canvas.getWidth()/30,circle);
canvas.drawCircle(canvas.getWidth()/2,(float)newPosY,canvas.getWidth()/40,circle);
but didn't get a curve line more like parte of a circle(changing the value of midr and midl got closer but still was't quite a line). Maybe with a bit of more tests could get the line but for now only need the circle, for anyone that also trying to get the curve line leaving the code and +1 for #Bojan Kseneman for pointing in the right direction.
You should make a custom View and draw stuff like that with the Canvas. You have to draw two paths (two curves) and a circle in the middle. Here is the basic idea, you will have to do the rest of the work on your own.
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path pathLeft = new Path();
pathLeft.moveTo(x1, y1);
pathLeft.quadTo(x1, y1, x2, y2);
Path pathRight = new Path();
pathLeft.moveTo(x1, y1);
pathLeft.quadTo(x1, y1, x2, y2);
canvas.drawPath(pathLeft, mPathPaint);
canvas.drawPath(pathRight, mPathPaint);
canvas.drawCircle(x, y, radius, paint);
}
Probably this question might be duplicate.But I am finding hard to get answer as I am new to OpenCV and Canvas drawing on view for android here is my code
List<Point> pts = new ArrayList<Point>();
Converters.Mat_to_vector_Point(MatOfPoint, pts);
I am getting List correctly,where Point abstract org.opencv.core.Point.
Now i am converting those points to android.graphics.Point coordinate using correct MatOfPoint.
android.graphics.Point pt1 = new android.graphics.Point((int) pts.get(0).x, (int) pts.get(0).y);
On getting this, I am trying to draw Canvas using android.graphics.Point, but coordinates are no matching up with image coordinates. Check the code given below.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(3);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.parseColor("#55000000"));
paint.setStyle(Paint.Style.FILL);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
canvas.drawPaint(paint);
canvas.drawLine(point1.x,point1.y, point2.x, point2.y, paint);
}
The canvas drawn with the detected square from openCV coordinate does not match the canvas Point coordinates. Have I to manipulate the points with pixels or density of image? Any help will be appreciated.
Thanks
you need to scale the point and shift point's position by adding offset
see line 412 in CameraBridgeViewBase.java
see line 171 in JavaCameraView.java
scale=Math.min(mOpenCvCameraView.getWidth()/Matwidth,mOpenCvCameraView.getHeight())/Matheight)
xoffset=(mOpenCvCameraView.getWidth()-scale*Matwidth)/2
yoffset=(mOpenCvCameraView.getHeight()-scale*Matheight)/2
final point1's X coordinate is: point1.x*scale+xoffset
final point1's Y coordinate is: point1.y*scale+yoffset
final point2's X coordinate is: point2.x*scale+xoffset
final point2's Y coordinate is: point2.y*scale+yoffset
Points which you have calculated with opencv, references coordinates on your MAT( or on your bitmap image).
You have to scale these coordinates to your display object in order to fit your line on image.
You can use the code below to achieve your goal.
Hope it helps.
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(3);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.parseColor("#55000000"));
paint.setStyle(Paint.Style.FILL);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
canvas.drawPaint(paint);
//iv is the ImageView which you can draw canvas over it
// imgbitmap is bitmap image
double scaledWidth=iv.getWidth();
double scaledHeight=iv.getHeight();
double xScaleFactor= scaledWidth/imgbitmap.getWidth();
double yScaleFactor= scaledHeight/imgbitmap.getHeight();
android.graphics.Point canvas_point1 = new android.graphics.Point((int)((point1.x*xScaleFactor)),(int)((point1.y*yScaleFactor)));
android.graphics.Point canvas_point2 = new android.graphics.Point((int)((point2.x*xScaleFactor)),(int)((point2.y*yScaleFactor)));
canvas.drawLine(canvas_point1.x,canvas_point1.y, canvas_point2.x, canvas_point2.y, paint);
}
I have to draw a custom shapeDrawable consisting of a triangle inside a circle. I can draw the circle and the triangle the question is that i want the triangle to be transparent but when i give a transparent color to the path drawing a triangle i will see the color of the circle insde the triangle i want to not have the color of the circle as backround of the triangle ?
here's the code i'm using :
#Override
protected void onDraw(Canvas canvas) {
Paint p = new Paint ();
int x = 1;
int y = 1;
Rect bounds = canvas.getClipBounds ();
p.setColor (color.getBackgroundColor());
p.setStyle(Style.FILL);
p.setStrokeWidth (0);
Path path = new Path();
Point p1 = new Point(bounds.centerX()-bounds.height()/4, bounds.centerY()-bounds.height()/4);
Point p2 = new Point(bounds.centerX()-bounds.height()/4, bounds.centerY()+bounds.height()/4);
Point p3 = new Point(bounds.centerX()+bounds.height()/4, bounds.centerY());
path.moveTo(p1.x, p1.y);
path.lineTo(p2.x, p2.y);
path.lineTo(p3.x, p3.y);
path.close();
Paint pTriang = new Paint();
pTriang.setColor(Color.TRANSPARENT);
pTriang.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
canvas.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.height()/2, p);
canvas.drawPath(path, pTriang );
}
BTW i'm overriding an ImageView!
Instead of trying to draw the Triangle, how about clipping the canvas?
/* set up triangle path... */
path.close();
canvas.save();
canvas.clipPath(path, Region.Op.XOR);
canvas.drawCircle(...);
canvas.restore();
I think you need to set the layer type to software on Honeycomb and later. Add this at the end of your constructor:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
Path path = new Path();
path.moveTo(0, 0);
path.quadTo(100, 0, 200, 200);
// more quadTo calls
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(20);
paint.setColor(Color.BLACK);
canvas.drawPath(path,paint);
From the path used to draw the stroke, is there a way to compute the inner and outer paths, in red and blue on the picture below ?
Hmmm...
How about:
1. draw double width stroke first, then draw fill
2. clip path, then draw double width stroke
I would like to draw a curve connecting three points in my screen
PointA = (480,46)
PointB = (160,137)
PointC = (0,228)
How to draw the curve using Android APIs?
Whatever i wanted, i could to produce it by using the following code :
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
PointF mPoint1 = new PointF(w/1.2F, h/1.2F);
PointF mPoint2 = new PointF(w/24, h/1.2F);
Path myPath1 = new Path();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
myPath1 = drawCurve(canvas, paint, mPoint1, mPoint2);
canvas.drawPath(myPath1, paint);
}
private Path drawCurve(Canvas canvas, Paint paint, PointF mPointa, PointF mPointb) {
Path myPath = new Path();
myPath.moveTo(63*w/64, h/10);
myPath.quadTo(mPointa.x, mPointa.y, mPointb.x, mPointb.y);
return myPath;
}
This will find the two sides of the screen (Landscape mode) and will draw a perfect curve across the screen.