I am facing problme in rotating image
Following code works fine
Matrix matrix = new Matrix();
matrix.postRotate(DEGREE,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
Bitmap m = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),mBitmap.getHeight(), matrix, true);
canvas.drawBitmap(m, mX, mY, null);
But I dont want to create a new bitmap again and again so I am using the following code
Matrix matrix = new Matrix();
matrix.postTranslate(mX, mY);
matrix.postRotate(DEGREE,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, matrix, null);
In that case image goes out of the view. It is not visible.
Matrix matrix = new Matrix();
canvas.translate(mX, mY);
canvas.drawBitmap(...);
canvas.translate(-mX, -mY);
Try first rotating it then translating it, because when you translate it first the center is not in the middle any more so you are rotating it with wrong pivot coordinates.
The pivot point by default when rotating is the top left corner of the image, which is why the view goes out of view. You need to add logic to make the pivot point the center of the image. Unfortunately, geometry is not my strong suit so maybe someone who somewhat enjoys geometry can give you the calculations to make this happen.
Related
I have an image in drawable folder for clock hand. I want to rotate it in fixed point like a clock hand. I have tried below code which rotates the hand in circular path around a fixed point but not as like clock hand.
Matrix matrix = new Matrix();
matrix.reset();
matrix.preTranslate(0, 0);
matrix.postRotate(angleRotation, -0, -0);
matrix.postTranslate(240, 480);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, matrix, null);
I am struggling for hours to get it sorted out. Any help will be greatly appreciated.
I have tried below links for help as well with no success.
SurfaceView, draw image and reduce size, rotate image
Android: How to rotate a bitmap on a center point
How to rotate a bitmap in Android about images center smoothly without oscillatory movement
I found the answer. Let px and py be any point on canvas. bitmap.getWidth()/2 is middle point along bitmap width. It can be any point for x cordinate. For y cordinate I have taken it as 10. angleRotation is the angle that is as per required.
So matrix.postTranslate(-bitmap.getWidth()/2, -10); is the point of rotation.
Below is the code.
Matrix matrix = new Matrix();
matrix.reset();
Paint paint = new Paint();
float px = 240;
float py = 480;
matrix.postTranslate(-bitmap.getWidth()/2, -10);
matrix.postRotate(angleRotation);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, paint);
Above code satisfy my requirements. Please modify it as per your need.
I use this to rotate my bitmaps.
private Bitmap rotateImage(Bitmap src,int degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
}
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 have tried several hours to rotate a bitmap with no success. I have read numerous articles about this subject on this web site and it seems the prefered solution involves creating a temporary canvas. Well I did this and I still do not see a roated bitmap.
My bitmap is a 40x40 blue square and I am trying to rotate it 45 degrees. Thats not asking for much is it? When the code runs, the bitmap that appears on the screen is the non-rotated original. ( I have also tried a translate with no success as well)
Here is my code:
// Load the bitmap resource
fillBMP2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.test1);
// Copy to a mutable bitmap
mb = fillBMP2.copy(Bitmap.Config.ARGB_8888, true);
// Create canvas to draw to
Canvas offscreenCanvas = new Canvas (mb);
// Create Matrix so I can rotate it
Matrix matrix = new Matrix();
matrix.setRotate (45);
offscreenCanvas.setMatrix (matrix);
// Send the contents of the canvas into a bitmap
offscreenCanvas.setBitmap(mb);
Later in an OnDraw I do the following:
canvas.drawBitmap(mb, 200, 200, null);
Any ideas what I am doing wrong? Seems like it should work.
Thanks
Try using this
Matrix matrix = new Matrix();
matrix.setRotate(15);
canvas.drawBitmap(bmp, matrix, paint);
setRotation method takes in a float representing
the degrees of rotation.
Try this...
Matrix matrix = new Matrix();
float px = 200;
float py = 200;
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getWidth()/2);
matrix.postRotate(45);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, paint);
You definitely want to use transformations: check out this link.
Basically it's this:
// save the canvas
ctx.save();
// move origin to center
ctx.translate(x,y);
// rotate
ctx.rotate(angle * (Math.PI / 180));
// draw image
ctx.drawImage(image, x, y, w, h, .w/2, h/2, w, h);
// restore
ctx.restore();
How can I inverse the image drawed into a Canvas?
I has the following:
canvas.save();
canvas.drawBitmap(image.current(), null, currentBounds(), Paints.BLANK);
canvas.restore();
How can I make the current image be drawed fliped on x-axis into the currentBounds()?
I already found some answers indicating usage of Matrix, but I wan't to know if there's a easier way? Such a Paint with some flag turned on.
EDIT:
Following is my try with Matrix transformations:
Rect currentBounds = currentBounds();
currentBounds.offset((int)offset.x(), (int)offset.y());
float scale = image.current().getWidth() / currentBounds.width();
Matrix matrix = new Matrix();
matrix.setScale(- scale - 1, scale + 1);
matrix.postTranslate(currentBounds.left, currentBounds.top);
canvas.drawBitmap(image.current(), matrix, Paints.BLANK);
canvas.drawRect(currentBounds, Paints.STROKE_BLUE);
The following is the result of this draw:
https://dl.dropbox.com/u/28683814/game.png
As can be seen, the sprite is being drawed from 0,0 to left and it's not fully completes the currentBounds(), what I'm doing wrong?
Use
canvas.scale(-1,0,width/2,height/2);
as mentioned by my own answer here.
Although, I would point out that it will take you about a minute to understand Matrices, and it'll make you a better Android programmer.
Use this. I think this is quite easy.
canvas.save();
canvas.rotate(180, x, y);
canvas.drawBitmap(bitmap, x, y, null);
canvas.restore();
Well, I solved this way:
Rect currentBounds = currentBounds();
currentBounds.offset((int)offset.x(), (int)offset.y());
float scale = (float) currentBounds.width() / (float) image.current().getWidth();
boolean leftMovement = movingLeft();
Matrix matrix = new Matrix();
matrix.setScale(leftMovement ? -scale : scale, scale);
matrix.postTranslate(leftMovement ? currentBounds.right : currentBounds.left, currentBounds.top);
canvas.drawBitmap(image.current(), matrix, Paints.BLANK);
But this "leftMovement ? currentBounds.right : currentBounds.left" does not looks right
I have a bitmap flush with the bottom of my screen. When the user clicks a button I want it to rotate to the right by one degree. I am able to accomplish this but the problem is that the bottom of the item is no longer flush with the screen. I need it to appear to rotate on its bottom axis. I could use some hack to increment the x and y when its rotated (using trial and error I suppose) but is there a formula or something more elegant I can use?
public void rotate(int degrees)
{
Matrix mat = new Matrix();
mat.postRotate(degrees);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mat, true);
}
Could you not instead use the following method that Matrix also has:
postRotate (float degrees, float px, float py)
It enables rotation on the specified point.