5

If I have a canvas, on which I draw a Bitmap like this:

canvas.drawBitmap(bmLargeImage, srcRect, destRect, paint);

and I scale the bitmap:

canvas.scale(1.5f, 1.5f, 450, 250);

I want to get the position of the Bitmap after the scale. If the position before scale was (0, 0), after scale there is a offset and I need that offset.. how can I get it?

Thanks and sorry for the simple question, newbie here...

Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
Sunne Rotterz
  • 63
  • 1
  • 4
  • You have to calculate it, here is a hint: http://stackoverflow.com/questions/6749723/android-get-bitmap-rect-left-top-right-bottom-on-a-canvas/6750631#6750631 – Lumis Jul 26 '11 at 20:06
  • so If I have objectOldX = 0, and pivotX is 360, and scaleX is 1.3, then the new object would be 0 + (0 - 360)*1.3, which gives -468 .. hm .. will check now. – Sunne Rotterz Jul 26 '11 at 20:31

3 Answers3

15

Ok lets try to work out the best formula for this

canvas.scale(scaleX, scaleY, pivotX, pivotY);  

if (scaleX >= 1){    
  objectNewX = objectOldX + (objectOldX - pivotX)*(scaleX - 1); 
}else{   
  objectNewX = objectOldX - (objectOldX - pivotX)*(1 - scaleX); 
}

The same for objectNewY. The new width and height of the bitmap would of course be the multiple of the old size and scale.

Lumis
  • 21,517
  • 8
  • 63
  • 67
  • this is awesome man! can you gimme example on how to do it for other corners :( I am newbie I know, and I lack math knowledge :( thanks a lot man! – Sunne Rotterz Jul 26 '11 at 21:09
  • There are two ways. One is to use the same formula for the opposite corner and another is to calculate the new size and add it to the new coordinates of top-left position which resulted from the code above. – Lumis Jul 26 '11 at 21:13
  • 2
    I can't vote you up since I am new, otherwise would give you all the karma in the world. :) thanks. – Sunne Rotterz Jul 26 '11 at 21:22
  • is there any example for other corners...:( m unable to handle them...plz – Awais Tariq Sep 29 '11 at 09:42
  • 1
    I was going to post my question regarding canvas restriction but I found your formula. How can I thank?? :).You really helped me. You thank you,thank you,thank you,thank you so much. – Bhavesh Hirpara Jun 14 '12 at 04:53
4

I believe the cleanest Solution would be to use the underlying transformation Matrix of the Canvas you are manipulating.

In Android there is the canvas.getMatrix(Matrix cmt) method available which will yield it. The transformation matrix will transform any point in world space you throw at into screen coordinates. Just use the matrix.mapPoints(float[] points) and you will be fine.

FYI, you can easily do it the other way around too. If you want to know what screen coordinate maps to which point in world space, e.g. for tapping; the inverse matrix can be used for that. It can be obtained via the matrix.invert(Matrix out) method. Use its mapPoints() for the coordinate mapping then.

Here are the official docs: mapPoints(), invert(), getMatrix()

Felix Ruzzoli
  • 81
  • 1
  • 6
2

If you'd like know the corners of your screen relative to your original canvas, you can use canvas.getClipBounds(). This returns a Rect with edge coordinates relative to your original canvas. For instance, if you start off with a canvas size of 320 x 480 and call

canvas.scale(2, 2, getWidth()/2, getHeight()/2);

and then

canvas.getClipBounds();

you will have a Rect (call this rect) where

rect.top == 120
rect.bottom == 360
rect.left == 80
rect.right == 240
aostiles
  • 75
  • 4