Expanding the drawing on canvas for android - android

So the scenario is that I have a surfaceView of size 640 x 480 on which I am showing on camera preview. Now I draw a something vertically on the screen. After that I am rotating the canvas using
canvas.rotate(90, getWidth()/2, getHeight/2);
Once I do that, I am expecting my drawing to be scaled and drawn horizontally. It does draw it horizontally but it is not scaling it according the width and height.
Here is the pictorial example explanation to help you understand better.
https://lh4.googleusercontent.com/-2wlImCt0m88/UcHzhKUSGBI/AAAAAAAAB9Y/bGNMOTu9DqM/s1440/canvas_rotation.png
Is there a way or an algorithm by which I can rotate the canvas and then scale it accordingly?
let me know if you need any further explanation.
Thanks in advance.

Well so I figured out the solution to it. What we can do is that we can use
canvas.scale( newX, newY, pivotX, pivotY);
/*
* Where
* newX = oldX * (newWidth/oldWidth);
* newY = oldY * (newHeight/oldHeight);
* pivotX = same as before;
* pivotY = same as before;
*/

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

Drawing a circle on a particular pixel of image

I have drawn a circle in a canvas with image in it on click event in one activity. And I have taken the x and y coordinates of that circle. In another activity i want to draw the same circle at the same position but the image size is not same so it is pointing to different position. So, how can achieve this?
The new position of circle (newX, newY) must move at same ratio that image size change.
newX = oldX * (newImageWidth / oldImageWidth)
newY = oldY * (newImageHeight / oldImageHeight)
You may want to change the size of the circle same way.

Any ways of making pinch to zoom smoother

Is there any ways of implementing smooth pinch to zoom without using matrix?
I am building drawing app and I want it to have pinch to zoom.
I get pivot point for scaling with:
centerposX = mScaleDetector.getFocusX();
centerposY = mScaleDetector.getFocusY();
and for scaling then I use:
canvas.scale(scaleFactor, scaleFactor, centerposX, centerposY);
But the problem is that it immediately centers view at the pivot point and them zooms it, rather than using it as a guide for centering.
I've seen that this problem has been solved by using matrix, but I don't want to use them as I need to keep track of offsets, ZoomTranslations which are calculated from centerposX/Y and scaleFactor to put drawings where they belong on screen.
So is there any way to solve this pivot point problem smoothly?
Thanks!
After a week I understood that I need to use matrix and get absolute coordinates on the screen, so I used Gesture detector to set matrix scale
matrix.postScale(mScaleFactor, mScaleFactor, focusX, focusY);
In my onDraw method I used canvas.concat(matrix); so not only Bitmap, but WHOLE canvas get's matrix transformation, and to get real screen coordinates I used a method i found on stack-overflow:
public float[] getAbsolutePosition(float Ax, float Ay) {
matrix.getValues(m);
float x = width - ((m[Matrix.MTRANS_X] - Ax) / m[Matrix.MSCALE_X])
- (width - getTranslationX());
float y = height - ((m[Matrix.MTRANS_Y] - Ay) / m[Matrix.MSCALE_X])
- (height - getTranslationY());
return new float[] { x, y };
}
I call this every time in my onTouchEvent() method, supplying event.getX and event.getY() as arguments.
After that, everything is easy peasy, also because of this beautiful method I've got rid of ~4-5 variables which I had to use to find real touch location.

Android get bounds of rotated,scaled text on canvas

I have a textview with some text. Textview have touch events, so user can rotate, scale and translate text. For translation, rotation
and scaling i'm using canvas. Canvas is doing this inside onDraw() function. Now i want to have outer bounds of text when it is scaled or rotated, can anybody help me.
Thanks in Advance.
I try this piece of code to translate,rotate and scale text on canvas:
canvas.scale(fScaledFactorForTextview,fScaledFactorForTextview,getTextWidth() / (2.0f * getLineCount()) + fTranslationX, (getTextSize() * getLineCount()) / 2.0f + fTranslationY);
canvas.rotate(fDegrees, getTextWidth() / (2.0f * getLineCount()) + fTranslationX, (getTextSize() * getLineCount()) / 2.0f + fTranslationY);
canvas.translate(fTranslationX,fTranslationY);
In general it's easier to do this if you use a matrix, rather than direct rotate and scale calls like this. If you use a matrix, you can just apply those same adjustments to the matrix. Then you can easily translate any point from normal Cartesion coordinates to the altered coordinates by multiplying the coordinates by that matrix. Matrix even provides the mapPoints function to do that.

Simultaneous rotation, translation, and scaling of bitmap in android canvas

I'm trying to show a picture, which can be zoomed and panned, and that rotates with a compass reading. With the code below, all three actions kind of work, but they influence each other.
Here is what I want to achieve:
1. Rotate around the center of the screen
2. Scale leaving the same part of the picture in the center
3. Pan to the desired spot in the picture
Here is what is actually happening with the code below:
1. Rotation works as intended, around the center of the screen
2. Scaling works, but it scales around the center of the picture
3. Translation only works as intended if angle is zero, otherwise it's moving in a wrong direction
// the center of the view port
float centerX = screen.right/2;
float centerY = screen.bottom/2;
Matrix m = new Matrix();
m.preRotate(angle, centerX, centerY);
m.preScale(mScaleFactor, mScaleFactor, centerX, centerY);
// scaling the amount of translation,
// rotating the translation here gave crazy results
float x = mPosX / mScaleFactor;
float y = mPosY / mScaleFactor;
m.preTranslate(x, y);
canvas.drawBitmap(pic, m, null);
If I translate first, and later rotate, the translation works as intended but the rotation is not around the center of the view port anymore.
How can I apply all three transformations, without them influencing each other?
I'm not sure about the scaling around the centre of the image, but as for the translation being in the wrong direction is it not as a consequence of you rotating the image but not the translations? Maybe try something like this:
float x = (mPosX*(cos(angle) + sin(angle)) / mScaleFactor;
float y = (mPosY*(cos(angle) - sin(angle)) / mScaleFactor;
m.preTranslate(x, y);
Also does the matrix object have a method to apply an affine transformation directly? Because then you won't need to think about the order of operations.
The affine transformation might look something like this:
M = |mScaleFactor*cos(angle) sin(angle) x|
| -sin(angle) mScaleFactor*cos(angle) y|
| 0 0 1|
But this will rotate around the corner of the image so you need to use the preTranslate() function first like so:
Mt.preTranslate(-centerX,-centerY);
And APPLY Mt to pic before applying M and then after you need to apply -Mt

Categories

Resources