I have a drawable resource that I need to draw on a canvas. I need to have the drawable centered at point (x,y). Right now if I do canvas.drawBitmap(mBitmap, x, y, mPaint), (x,y) represent (left,top). Does anyone know how I may get the center of my drawable so I can place it on the canvas correctly?
Get the width and height of the canvas.
Now, you need to draw it on width/2 and height/2.
To be more centered, you can subtract from width/2 half of the bitmap width, and from height/2 half of the bitmap height.
canvas.drawBitmap(mBitmap, width/2-mBitmap.getWidth()/2, height/2-mBitmap.getHeight()/2, mPaint);
A Simple math...
int centerX = drawable.getIntrinsicWidth() / 2;
int centerY = drawable.getIntrinsicHeight() / 2;
Related
I'm looking at making something that looks like the following:
Which is basically a rectangle shape on the top left thats been rotated, and then two underneath it, tiled like it is.
I've had a go at doing it but just can't get it done, basically I use:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45);
canvas.drawRect(x/2, y/2, x/2+100, y/2+40, paint);
canvas.restore();
And I've noticed that what should be a rectangle rotated near the centre of the screen is instead one that is to the top right of the screen. When I try doing something similar to (0,0, 100,100) I don't get any rectangle at all.
I guess I'm confused whether the coordinate system changes when the rotation of the canvas is done, and what would be the easiest way in looking into getting the image above on android (besides just creating it in photoshop and adding the png).
The single argument rotate(angle) will use 0,0 as the pivot point.
If you want to rotate about your object, you should calculate some point on it to rotate about and use the 3 argument rotate(angle, pivotX, pivotY), ie:
int x = getWidth();
int y = getHeight();
canvas.save();
canvas.rotate(-45, x / 2, y / 2);
canvas.drawRect(x / 2, y / 2, x / 2 + 100, y / 2 + 40, paint);
canvas.restore();
I made your design just for fun:
int x = getWidth();
canvas.rotate(-45);
canvas.drawRect(-x, 0, x, h, green);
canvas.drawRect(-x, h, 0, 2 * h, purple);
canvas.drawRect(0, h, x, 2 * h, blue);
Where h is the height of the rectangle.
I am trying to set the anchor point to the middle of the bitmap. By default it is always the top-left corner of the bitmap.
If I try:
canvas.drawBitmap(bitmap, x, y, paint);
It always starts drawing the bitmap from the top left. However it can be fixed by subtracting half of the width/height to the x/y point.
int widthOffset = bitmap.getWidth()/2;
int heightOffset = bitmap.getHeight()/2;
canvas.drawBitmap(bitmap, x-widthOffset, y-heightOffset, paint);
Is there any other solution which sets the anchor by default to the center of the bitmap?
I want to rotate a bitmap image based on user click by 10 deg. Following numerous stackoverflow and google answers, I tried various combinations of Matrix rotation.
However the image doesn't really rotate as expected and gives a jittery view of rotation + oscillation about canvas center. To test I am increasing rotation angle by 10 deg (instead of clicks) each time object's draw method is called. The image is a symmetrical circle [64x64 enclosing rectangle] and I expect it to rotate at center of screen about it's own center like a wheel, but it rotates and moves diagonally towards right-down and moves back upto center of screen in an oscillatory fashion.
public void draw(Canvas canvas) {
Matrix matrix = new Matrix();
rotation += 10;
float px = this.viewWidth/2;
float py = this.viewHeight/2;
matrix.setRotate(rotation, bitmap.getWidth()/2, bitmap.getHeight()/2);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, getImgWidth(), getImgHeight(), matrix, true);
canvas.drawBitmap(newbmp, px - (getImgWidth()/2), py - (getImgHeight()/2), null);
}
Here is an example.
I broke it to 3 steps.
The first translate moves the bitmap so that it's center is at 0,0
Then a rotation,
and finally move the bitmap center to where you want it on the canvas.
You don't need the second bitmap.
Matrix matrix = new Matrix();
rotation += 10;
float px = this.viewWidth/2;
float py = this.viewHeight/2;
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, null);
As an optimization, create the Matrix once outside this method and replace the creation with a call to matrix.reset()
You need to translate the bitmap to the 0,0 point (or draw it at 0,0) and rotate it there, then translate it back, as such:
canvas.save();
canvas.translate(this.viewWidth, this.viewHeight);
canvas.rotate(rotation);
canvas.drawBitmap(newbmp, -(getImgWidth()/2), -(getImgHeight()/2), null);
canvas.restore();
Here I draw it with the center at 0,0 (I think), because when you rotate, it's about 0,0 and not the center of the screen as one would think. If you draw the center at 0,0 then it will rotate about the center of the bitmap.
If my code does not accomplish drawing the bitmap center at 0,0 then you can change my code to draw it at the center and it will work as you want.
Hope this helps!
// x : x coordinate of image position
// y : y coordinate of image position
// w : width of canvas
// h : height of canvas
canvas.save();
canvas.rotate(angle, x + (w/2), y + (h/2));
canvas.drawBitmap(image, x, y, null);
canvas.restore();
The steps are
Save the existing canvas
Rotate the canvas about the center of the bitmap, that you would draw on canvas with an angle of rotation
Draw the image
Restore the image
i want my compass to spin like this
but my result is that:
the compass is going everywhere in my screen...
where is my problem please?this is my compass.java code:
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GRAY);
int w = canvas.getWidth();
int h = canvas.getHeight();
int cw = w / 2;
int ch = h / 2;
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass);
canvas.translate(cw, ch);
if (mValues != null) {
canvas.rotate(-mValues[0]);
}
int cx = (mWidth - myBitmap.getWidth()) / 2;
int cy = (mHeight - myBitmap.getHeight()) / 2;
canvas.drawBitmap(myBitmap, cx, cy, null);
}
p.s.: i m sorry for the bad pictures but i really dont know how to explain my problem in english!Thanks
Since you have already translated to the center of the canvas, you may only need to offset the compass with its half width/height to center it. Try:
int cx = -myBitmap.getWidth() / 2;
int cy = -myBitmap.getHeight() / 2;
canvas.drawBitmap(myBitmap, cx, cy, null);
Also to get a good hang of transformations (translate, rotate), read The OpenGL Red book chapter 3, specifically the part Thinking about Transformations. While this is about OpenGL, you can use the knowledge for non-OpenGL transforms too.
EDIT:
Think in turtle logic. Your first translation takes your pencil to the center of your canvas. The rotation rotates your pencil. So now you could draw the compass exactly where the pencil is (no offsets), except that drawing the compass image is done starting from its top-left corner instead of its center. Therefore you need a last translation of (-compassWidth/2, -compassHeight/2). Note that this translation already occurs on the rotated x & y axes. Also note that you may pass 0/0 for cx/cy in drawBitmap if you manually apply that translation to the canvas itself.
So the full sequence is: translate to canvas center, rotate, translate negated to image center.
Don't decode the Bitmap in onDraw - do it when the view is created and reuse the Bitmap.
Make a Matrix and matrix.postRotate(mValues[0], half_width_of_bitmap, half_height_of_bitmap); and matrix.postTranslate(cw, ch);
Draw the bitmap with canvas.drawBitmap(bitmap, matrix, null);
i have a bitmap on canvas.i need to align bitmap to centre of canvas(centre of the image should be in centre of canvas.in my requirement,there should not give fixed points to align bitmap).while portrait view how to scale canvas and image appropriate to resolution?
public void onDraw(Canvas canvas) {
Bitmap imgtable = BitmapFactory.decodeResource(getResources(), R.drawable.table_01);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(imgtable, 10, 10, null);
}
While i do not know the specific methods of getting the canvas width and bitmap width in Android, to place an bitmap at the center usually goes something like this.
centreX = (canvasWidth - bitmapWidth) /2
centreY = (canvasHeight - bitmapHeight) /2
Then place your image at centreX,centreY