Getting output rectangle of drawBitmap has drawn a Bitmap using a Matrix - android

Bitmap b;
Matrix mMatrix;
mMatrix.reset();
// move the view so that it's center point is located in 0,0
mMatrix.postTranslate(-sizeX, -sizeY);
// scale the view
mMatrix.postScale(mScaleFactor, mScaleFactor);
// re-move the view to it's desired location
mMatrix.postTranslate(mTouchX, mTouchY);
canvas.drawBitmap(b, mMatrix, null);
I need to know if there is an built in method to tell the info like corner coordinates of where the Bitmap is printed, etc.
Hope it is clear.
Thanks.

yes, it's called mapRect https://developer.android.com/reference/android/graphics/Matrix.html#mapRect(android.graphics.RectF)
RectF r = new RectF(0, 0, b.getHeight(), b.getWidth());
mMatrix.mapRect(r);
// r now have the coordinates where the bitmap was drawn,
// you can test it by calling
canvas.drawRect(r, paint);

Related

Rotate bitmap in fixed point like a clock hand in SurfaceView

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);
}

Scaling and translating a bitmap in android

I am trying to sale a bitmap and translating it at each step.
If we look at the following code, I am drawing an image, translating and scaling it and then performing the same operations in reverse so as to get the original configuration back. But after applying the operations, I do get the original scaled image (scale factor 1) but the image is translated t a different position.
Could you please point out the correct method do so ? (In the example above, how do I reach the original configuration? )
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Matrix matrix = new Matrix();
scale = (float)screenWidth/201.0f;
matrix.setTranslate(-40, -40);
matrix.setScale(scale, scale);
canvas.drawBitmap(bitMap, matrix, paint);
//back to original
canvas.drawColor(0, Mode.CLEAR);
matrix.setScale(1.0f/scale, 1.0f/scale);
matrix.setTranslate(40,40);
canvas.drawBitmap(bitMap, matrix, paint);
}
You should just use the Canvas methods for scaling and translating, that way you can then take advantage of the save() and restore() APIs to do what you need. For example:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Save the current state of the canvas
canvas.save();
scale = (float) screenWidth / 201.0f;
canvas.translate(-40, -40);
canvas.scale(scale, scale);
canvas.drawBitmap(bitMap, 0, 0, paint);
//Restore back to the state it was when last saved
canvas.restore();
canvas.drawColor(0, Mode.CLEAR);
canvas.drawBitmap(bitMap, 0, 0, paint);
}
I think the problem with your original code might be because of the way scale and translate use the point around which you scale/translate. IF you specify the correct pivot points in between/for the operations, things will be ok.

Rotating Bitmap Not Rotating

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();

Inverse drawing of Bitmap on Canvas

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

Show portion of Bitmap image on canvas in Android

I am trying to build a Magnify tool in my Android app. For this, I have an ImageView, which I converted to Bitmap (with some zoom/scale factor).
imageView.setDrawingCacheEnabled(true);
Bitmap drawingCache = imageView.getDrawingCache(true);
Matrix matrix = new Matrix();
matrix.postScale(5, 5);
Bitmap viewCapture = Bitmap.createBitmap(drawingCache, 0, 0,
drawingCache.getWidth(),
drawingCache.getHeight(),
matrix, true);
imageView.setDrawingCacheEnabled(false);
Now, I am drawing this Bitmap image "viewCapture" to my canvas. Here, I want only portion of the image to be rendered on the canvas.
I tried using approaches: "setRectToRect() on Matrix", "canvas.drawBitmap(bitmap, src, dst, paint)". But, didn't work out appropriately.
Would using SurfaceViews be helpful? Has anyone come across this situation? Please post your thoughts/ideas.
Why not just use the following?
Canvas.drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
src corresponds to which region of the bitmap you want to draw and dst says where you want the bitmap drawn. You can read more about it here: http://developer.android.com/reference/android/graphics/Canvas.html
When I do that, I get a smaller image of the bitmap, instead of cropped image. Following is the snippet I have used.
Canvas c = holder.lockCanvas();
c.drawRGB(10, 10, 10);
Rect src = new Rect((int)x - _image.getWidth(), (int) y - _image.getHeight(), (int)x + _image.getWidth(), (int) y + _image.getHeight());
RectF dst = new RectF((int)x - 50, (int) y - 50, (int)x + 50, (int) y + 50);
c.drawBitmap(_image, src, dst, null);
holder.unlockCanvasAndPost(c);

Categories

Resources