I've a noob question about android dev.
I search how to draw a line with a text on it.
I visited a lot of website talking about it but no one answer me.
i've created this function :
private void creerLigne(float x, float y, float xend, float yend, int color) {
Bitmap bmp = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(), Config.ARGB_8888);
Canvas c = new Canvas(bmp);
mImage.draw(c);
Paint p = new Paint();
p.setColor(color);
p.setTextSize(50);
Path path = new Path();
path.moveTo(x - xend, y - yend);
c.drawTextOnPath("42", path, 0,30,p);
c.drawLine(x, y, xend, yend, p);
mImage.setImageBitmap(bmp);
}
With this, i've a line and the text but the text is in the top left hand corner :( .
Thanks for your help.
The coordinates x, y, xend, yend are all absolute positions within the image, right?
In this case the Path should be build as:
Path path = new Path();
path.moveTo(x,y);
path.lineTo(xend, yend);
c.drawTextOnPath("42", 0, 30, path, p); // baseline is 30 pixel above the path
In the Paint you can also set flags to ensure the text is centered along the path with p.setTextAlign(Paint.Align.CENTER)
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);
}
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);
I was trying to start a quadratic curve from (0, 0) to the bottom right of my device screen. I did some research and looks like I can use quadTo method in the Path class to achieve that. I wrote the following code but I don't see the curve is drawn:
int w = getDisplayWidth();
int h = getDisplayHeight();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
paint.setStrokeCap(Paint.Cap.ROUND);
PointF pt1 = new PointF(0, 0);
PointF pt2 = new PointF(w, h);
Path path = new Path();
// Find the mid point
float x2 = (pt2.x + pt1.x)/2;
float y2 = (pt2.y + pt1.y)/2;
// Move the path to the mid point
path.moveTo(x2, y2);
// Draw a cruve from 0,0 to w, h
path.quadTo(pt1.x, pt1.y, pt2.x, pt2.y);
m_canvas.drawPath(path, paint);
The output is the image below:
Did I miss something?
Thanks.
According to the documentation:
void quadTo(float x1, float y1, float x2, float y2)
Add a quadratic bezier from the last point, approaching control point
(x1,y1), and ending at (x2,y2).
Currently you are drawing a curve starting in the middle of the screen (x2,y2), through the (0,0) point and ending in (width, height).
Try something like this:
PointF pt1 = new PointF(0, 0);
PointF pt2 = new PointF(w, h);
PointF mid = new PointF(w, h/2);
Path path = new Path();
path.moveTo(0, 0);
path.quadTo(mid.x, mid.y, pt2.x, pt2.y);
draw a curved line with arrow from point1(x1,y1) to point2(x2,y2) like this
I'm developing an application in android canvas.
automata like application and I'm having trouble drawing a curved line with an arrow at the end.
pointing the next circle.
can u give me a code or suggestion about this?
I think what You need is a mix out of draw on path and line drawing. Declare this method inside Your onDraw:
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);
}
This is just a poor example, but itshould show where to start with.
I know i should leave comment but the code in the comment is hard to read, so i put up another answer.
The answer Opiatefuchs it's basally right. but there's 1 thing you should notice, if you want to test his code.
float centerWidth = canvas.getWidth()/2; //get center x of display
float centerHeight = canvas.getHeight()/2; //get center y of display
the centerWidth and the centerHeight should be obtained like below, or nothing would painted to your screen.
and the circleDistance = 200 is a bit large for a regular phone's screen( as for my device samsung i9300, 200 is too large, the second circle positioned out of the screen range. you change it to a smaller value 80 for example.)
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerWidth = w / 2;
centerHeight = h / 2;
}
the screenshot.
I have the following method:
protected void onDraw(Canvas i_Canvas) {
int x = (int) m_X;
int y = (int) m_Y;
Path path = new Path();
path.addCircle(
m_Cx,
m_Cy,
m_Radius,
Path.Direction.CCW);
i_Canvas.clipPath(path);
Rect rect = new Rect(x, y, x + 240, y + 240);
i_Canvas.drawBitmap(m_FullImageBitmap, rect, rect, m_Paint);
}
Using this I am trying to create a cropped area of some bitmap in a circle shape.
I also want to blur the edges of that circle area. For example: 5px from the edge towards the centre of the shape will be blurred. How can I implement this?
I think you would have to apply a BlurMaskFilter when drawing the image:
m_Paint = new Paint(0);
m_Paint.setColor(0xffffffff);
m_Paint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));