In a custom view, is there a way I can set the center of a drawable at a certain point on the canvas? (I don't want to deal with figuring out rectangular bounds for the drawable...)
When you make the call to draw the Bitmap, draw it at a point with it's left and top attributes set to the position minus half the image's width and height, respectively. That will center it at the point you want.
IE.
canvas.drawBitmap(bitmap, xPos - bitmap.getWidth()/2, yPos - bitmap.getHeight()/2, new Paint());
Related
I can't just seem to figure it out. I am trying to draw a segmented circle (what looks like circle inside a circle). However I want the segments to have specific colors and to be transparent inside the smaller circle. Preferably , I would like to make the color of the segmented lines different than the circle
Here are the solutions I had in mind:
1- Draw arc with fill color for the bigger circle and draw a circle for the small circle. 2 problems with this. First one is that the inner circle area is no longer transparent as it takes the color from the bigger one. Second problem is that the segmentation lines of the outer circle is going all the way to the center (not only to the inner circle perimeter)
2) Draw arcs for the bigger outer circle and draw circle for the inner circle. Set it to be color filled but don't show strokes. Then draw another outer circle on top with no fill just to show strokes. And then draw lines between the inner and outer circle using the calculations ( angle and radius) to determine where the lines are... Very convoluted solution, there has to be another way. Even with this solution, still have problem with the color showing in the center but maybe playing with gradient can help.
I read so much on SO but I couldn't figure the right answer as many answers would remove the control of circle parameters
HEELP!!!
#Override
public void draw(Canvas canvas) {
float size = Math.min(getWidth(),getHeight());
paint.setStrokeWidth(size/4);
paint.setStyle(Paint.Style.STROKE);
final RectF oval = new RectF(0, 0, getWidth(), getHeight());
oval.inset(size/8,size/8);
paint.setColor(Color.RED);
Path redPath = new Path();
redPath.arcTo(oval, 0, 120, true);
canvas.drawPath(redPath, paint);
paint.setColor(Color.GREEN);
Path greenPath = new Path();
greenPath.arcTo(oval, 120, 120, true);
canvas.drawPath(greenPath, paint);
paint.setColor(Color.BLUE);
Path bluePath = new Path();
bluePath.arcTo(oval, 240, 120, true);
canvas.drawPath(bluePath, paint);
paint.setStrokeWidth(2);
paint.setColor(0xff000000);
canvas.save();
for(int i=0;i<360;i+=40){
canvas.rotate(40,size/2,size/2);
canvas.drawLine(size*3/4,size/2,size,size/2,paint);
}
canvas.restore();
final RectF ovalOuter = new RectF(0, 0, getWidth(), getHeight());
ovalOuter.inset(1,1);
canvas.drawOval(ovalOuter,paint);
final RectF ovalInner = new RectF(size/4, size/4, size*3/4,size*3/4);
canvas.drawOval(ovalInner,paint);
}
I'm drawing arcs using the Path class and strokes. Style.STROKE gives arcs without filling. Stroke width is set to size/4 which is a quarter of the view. Half of that stroke width goes outside and the second half goes inside, like this:
xxxxxxxx outer border of the arc of width 5
xxxxxxxx
------------ stroke
xxxxxxxx
xxxxxxxx inner border of the arc
That's why I'm using insets - I need to offset the stroke a bit in order to fit it in the view. Without insets the arcs are cut by all four sides of the view.
And why canvas rotation? Because it's easier to rotate the canvas with built-in methods than calculate lines manually. Rotation uses trigonometric functions and quickly becomes quite complex, hard to read and error prone. Basically I'm rotating the paper and drawing straight lines.
If I use this:
mCamera.rotateY(45);
mCamera.getMatrix(mMatrix);
mMatrix.preTranslate(-pivotX, -pivotY);
mMatrix.postTranslate(pivotX + centerX, pivotY + centerY);
And do:
canvas.drawBitmap(bitmap, mMatrix, null);
Then the drawn picture will be taller and slimmer and the matrix will be nicely applied to the whole picture. Now, is there any way to calculate the rotated size? I want to fit the image by scaling it and now when I rotate it some of the top and bottom is clipped because of the parent's constraints. Thanks!
EDIT:
What I am going to do is spin the image and the range for rotateY will be from 0 to 90.
Well, you could easily let the matrix map the corners of your bitmap and then calculate the bounds, as the mapped corners will be the max / min for x and y coordinate. Maybe you can do it without too many if clauses :)
Edit:
Check out
RectF r = new RectF(/*your bitmap's corners*/);
matrix.mapRect(r);
That way you should get r's new size.
If you stick to 45° then Pythagoras is the key
Everytime I use this code nothing is drawn. I need to draw a bitmap inside of a specified rectangle.
canvas.drawBitmap(MyBitmap, null, rectangle, null)
I've looked online but can't find much help.
EDIT
The original answer is incorrect.
You can use the sourceRect to specify a part of a Bitmap to draw.
It may be null, in which case the whole image will be used.
As per the fryer comment he was drawing beneath something, I'll add a note on that.
drawBitmap(bitmap, srcRect, destRect, paint)
does not handle Z ordering (depth) and the order of calling draw on object matters.
If you have 3 shapes to be drawn, square, triangle and circle. If you want the square to be on top then it must be drawn last.
You're not specified any source, so its not drawn anything.
Example:
You have a Bitmap 100x100 pixels. You want to draw the whole Bitmap.
canvas.drawBitmap(MyBitmap, new Rect(0,0,100,100), rectangle, null);
You want to draw only the left half of the bitmap.
canvas.drawBitmap(MyBitmap, new Rect(0,0,50,100), rectangle, null);
You need to specify the source rect, the source rect can be a rectangle anywhere from 0,0 to the width,height of the bitmap.
The main item to remember when defining the Rect is:
left < right and top < bottom
The rect is in screen coordinates (positive Y downward) ...
I find it helpful to think of the Rect arguments
(left, top, right, bottom)
as
(X, Y, X + Width, Y + Height)
where X,Y is the top left corner of the sprite image.
NOTE: If want to center the image on a particular location, remember to offset those values by half the sprite width & height. For example:
int halfWidth = Width/2;
int halfHeight = Height/2
Rect dstRectForRender = new Rect( X - halfWidth, Y - halfHeight, X + halfWidth, Y + halfHeight );
canvas.drawBitmap ( someBitmap, null, dstRectForRender, null );
This uses the whole original image (since src rect is null) and scales it to fit the size and position from dstRectForRender ... and using the default Paint.
I dont know why but this worked for me!
Rect rectangle = new Rect(0,0,100,100);
canvas.drawBitmap(bitmap, null, rectangle, null);
Thanks:)
In my view I have a big rectangle, the rectangle can move. When the rectangle moves to someplace, I want to draw image in the center of the big rectangle. My question is that I cannot put the center of the image to the center of the rectangle.
I used:
canvas.drawBitmap(rotatedBitmap, matrix, paint)
canvas.drawBitmap(rotatedBitmap, left, top, paint)
but i cannot find canvas.drawBitmap(rotatedBitmap, centerX, centerY, paint), so I want to use matrix, but the matrix also moves image from the left and top start, not from center, can you give some clue to draw the pic in the center of the rectangle?
Try using the bounds of the rectangle as a reference point, then use something like:
imageStartX = (rectStartX + (rectWidth/2)) - (imageWidth/2);
imageStartY = (rectStartY + (rectHeight/2)) - (imageHeight/2);
How can I draw rectangle at start and end points but still maintain the same width? ie 10 pixels width.
Rect simplr = new Rect();
simplr.set(start.x, start.y, end.x, end.y);
thank you
Thickness is normally something you set in the Paint, not in the Rect.
See http://developer.android.com/reference/android/graphics/Paint.html#setStrokeWidth(float)