Scaling canvas and keeping center - android

I'm want to scale a canvas with a bitmap drawn on it. I'm able to scale the canvas but the bitmap drawn on it moves to the upper left respectively lower right.
#Override
protected void onDraw(Canvas canvas) {
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
//draw bitmap
}
For the last few days I tried many different approaches from manipulating translation coordinates to pivot points for scaling. But nothing did work for me. I'm pretty sure there must be an easy solution for my problem.
Thanks in advance

Like you mentioned, the pivot point is the correct way to do this:
canvas.scale(2,2, redCircle.x, redCircle.y);
will work. There is no need for extra translation.

var widthNew = ctx.canvas.width / 2;
var heightNew = ctx.canvas.height / 2;
ctx.setTransform(scale,0,0,scale,-(scale-1)*widthNew,-(scale-1)*heightNew);
This will help you scale the canvas horizontally and vertically with the horizontal and vertical translation.

Related

Issue on scaling a Canvas in Android

I have a code to scale drawing canvas.
So i tried this code. i scale it but it moves down,
here is my code:
canvas.save();
scaleA = 1.1;
scaleB = 1.1;
canvas.scale(scaleA, scaleB);
canvas.restore();
the issue is even when i scale the Y coordinates move down, so i try to translate or reduce y coordinates but i still issue. any one knows how to properly scale a drawing canvas?
i tried like this:
canvas.save();
scaleA = 1.1;
scaleB = 1.1;
canvas.translate(scaleA, -scaleB);
canvas.scale(scaleA, scaleB);
canvas.restore();
You have to set the center of your image, if your image center is equal to the canvas(view) center
canvas.scale(sx, sy, canvas.getWidth() / 2, canvas.getHeight() / 2);
Or else, change the last two params to whatever center you want it to be, you don't need to translate

android get bitmap width and height after scaled by matrix

I use matrix to scale a bitmap and draw it on canvas, after it's scaled, is there a way to get the scale with of the bitmap? and it's scale height?
sx += 0.5f;
matrix.setScale(sx, sx);
matrix.postTranslate(left, top);
canvas.drawBitmap(bitmap, matrix, paint);
// here how to get the scaled width of bitmap?
This is part of my current project - a simple meme maker, so another question is that is there any good tutorials or resource (open source app) I can learn? I googled a lot, just get some pieces no complete tutorials.
Thanks.
I believe
Bitmap#getScaledHeight (Canvas canvas)
should do the job. If not try with
final int scaledHeight = bitmap.getHeight() * sx;
but the first one should work.

Android: Scaling ImageView and it's onDraw() items

All, I've extended the ImageView in order to implement pinch and zoom scaling on the image. This is done by modifying the matrix and applying it to the image. Now, I am also overwriting the onDraw() to draw primitives (i.e. rectangles and circles). I've applied the matrix to the canvas and it appears to have handled the scaling properly, but the only problem is that that position is off on the drawn items. How do I go about translating the positions of the drawn items to reflect the new scale?
There is an aproach without matrix, you can implement the pinch and zoom directly in the onDraw method. Check this blog post: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX, mPosY);
mIcon.draw(canvas);
canvas.restore();
}

Canvas Zoom goes to point (0,0)

I am having a problem in zooming the canvas. I have made a customized view in which I am drawing relationship diagrams now when I zoom out the canvas in goes to the position (0,0). I have seen different threads and questions but could not find appropriate answer.
What i am doing in onDraw Method is.
canvas.scale(mScaleFactor, mScaleFactor);
I have also seen the canvas.scale(x, y, px, py) method but i do not know how to get the pivot points of x and y.
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.4f, Math.min(mScaleFactor, 5.0f));
if(mScaleFactor>=1)
mScaleFactor=1f;
invalidate();
return true;
}
The pivot points are basically the point that your canvas will be transformed around, so scaling with a pivot of 0,0 makes it shrink towards that point.
using the following method you can change the pivot point to wherever you want it:
canvas.scale(x, y, px, py);
Now for the new stuff:
If you want your canvas to be scaled towards its centre, you will just have to know the point in the middle of your canvas:
float cX = canvas.getWidth()/2.0f; //Width/2 gives the horizontal centre
float cY = canvas.getHeight()/2.0f; //Height/2 gives the vertical centre
And then you can scale it using those coordinates:
canvas.scale(x, y, cX, cY);
Take a look at these two answers, they describe the problem and its solutions very well.
Android Bitmap/Canvas offset after scale
Scaling image of ImageView while maintaining center point in same place

Android canvas.scale(-1,1)

So my aim is to flip an image horizontally then draw it on a canvas. Currently I'm using canvas.scale(-1,1) which effectively works and draws the image horizontally, however it also screws with the x axis values where before the scale the x position would be 150 and after I'd have to switch it to -150 to render in the same spot.
My question is, how can I make it so the x value is 150 in both cases without having to adjust the x position after the scale? Is there a more effective way to do this without taking a hit on performance?
I know this question is old, but I happened to bump into the same problem. In my situation, I had to flip the canvas when drawing on a class extending an ImageButton. Fortunately, the solution for this specific case was more elegant than I thought. Simply override the onDraw(Canvas) method as follows:
#Override
protected void onDraw(final Canvas canvas) {
// Scale the canvas, offset by its center.
canvas.scale(-1f, 1f,
super.getWidth() * 0.5f, super.getHeight() * 0.5f);
// Draw the button!
super.onDraw(canvas);
}
I've fixed this by applying the transformation to the bitmap prior to ever using it like this:
public void applyMatrix(Matrix matrix) {
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
}
...
Matrix matrix = new Matrix();
matrix.preScale(-1, 1);
mSprite.applyMatrix(matrix);
Did you try repeating the canvas.scale(-1, 1)? It will effectively remove the transformation, since two negatives make a positive.

Categories

Resources