I am using a Path to draw a function to the Canvas. The problem I am facing is that the function is not scaled in the x axis. I tried using Canvas.sacale() in the onDraw() method but it made the path drawing blur. How can I stretch the path drawing in the x axis with out the blur.
If you try to scale the Canvas it will blur as if it is a bitmap. You should use some property from animation geometry to scale the Path.
Matrix matrix = new Matrix();
RectF rectF = new RectF();
your_path.computeBounds(rectF, true);
matrix.setScale(1.25f, 1f or 0f, rectF.centerX(), rectF.centerY());
your_path.transform(matrix);
Related
I basically need to rotate 90 degres a small part of an ImageView (e.g):
In the Image above, I'd like to rotate the 4 so it displays correctly. Only the 4, the rest should remain vertical as it is.
Is there a way I can achieve it?
By Implementing the method suggested by MikeM. I'm getting the following result.
As you can see there are two major things I need to fix:
The rotated square is working, although in the wring position. How do I found out the exact coordinates of the 4
The background of the image, has been changed to black. It used to be transparent
If you know, or can figure, the coordinates and dimensions of the region you'd like to rotate, then the process is relatively straightforward.
Load the image as a mutable Bitmap.
Create a second, rotated Bitmap of the desired region from the original.
Create a Canvas on the original Bitmap.
Clear the clipped area, if necessary.
Draw the rotated region back onto the original.
In the following example, it's assumed that the region's coordinates (x, y) and dimensions (width, height) are already known.
// Options necessary to create a mutable Bitmap from the decode
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
// Load the Bitmap, here from a resource drawable
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resId, options);
// Create a Matrix for 90° counterclockwise rotation
Matrix matrix = new Matrix();
matrix.postRotate(-90);
// Create a rotated Bitmap from the desired region of the original
Bitmap region = Bitmap.createBitmap(bmp, x, y, width, height, matrix, false);
// Create our Canvas on the original Bitmap
Canvas canvas = new Canvas(bmp);
// Create a Paint to clear the clipped region to transparent
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
// Clear the region
canvas.drawRect(x, y, x + width, y + height, paint);
// Draw the rotated Bitmap back to the original,
// concentric with the region's original coordinates
canvas.drawBitmap(region, x + width / 2f - height / 2f, y + height / 2f - width / 2f, null);
// Cleanup the secondary Bitmap
region.recycle();
// The resulting image is in bmp
imageView.setImageBitmap(bmp);
To address the concerns in the edit:
The rotated region's figures in the original example were based on the image with the long axis vertical. The image in the edit had been rotated to vertical after that region had been modified.
The black background was due to having inserted the resulting image into MediaStore, which saves images in the JPEG format, which does not support transparency.
I am developing an application where is included crop functionality and in this I'm blocked at below scenario.
The scenario:
Crop overlay is not circulating the whole image when we apply straightening to the image if we change the crop overlay, ratio also is not working.
I got the code from google but it is related to matrix, I have tried using matrix, but here I need to find the coordinates(edges) of matrix to move the overlay.
How to find it? If anyone has any idea please help me...
I added the image to explain the problem
Thanks in advance..
I am using the below code but I didn't get the exact coordinates of the matrix
RectF r = new RectF();
mymatrix.mapRect(r);
Rect rect =
new Rect((int)r.left,int)r.top,int)r.right+width,int)r.bottom+height);
You should not use mapRect if you are applying rotation on your matrix. My advice is to figure out the 4 initial points representing each rectangle edge (the image itself) and use mapPoints instead.
Lets say you have an image 200px wide and 200px tall with its top left corner positioned at origin (0,0).
If you rotate this image from its center (100,100) 45 degrees and then scale it 200% from its center we will have the following scenario:
//original image coords
float[] points = {
0f, 0f, //left, top
200f, 0f, //right, top
200f, 200f, //right, bottom
0f, 200f//left, bottom
};
Matrix matrix = new Matrix();
//rotate 45 degrees from image center
matrix.postRotate(45f, 100f, 100f);
//scale 200% from center
matrix.postScale(2f, 2f, 100f, 100f);
//get the new edges coords
matrix.mapPoints(points);
After calling matrix.mapPoints(points) the points array will have the updated coords. This means points[0], points[1] will have the new left top image coord and so on.
The even indices represents the abscissas and the odd indices represents the ordinates on the points array.
I want to calculate center of a bitmap that is drawn on a canvas with a matrix, it can be rotated, scaled or translated with a arbitrary value. What is the easiest way to find center of the this bitmap on canvas?
You need to apply the matrix to the coordinates of the center of bitmap.
If you use a canvas that has a transformation matrix, you can get the final matrix through Canvas.getMatrix()
If you draw the Bitmap on the Canvas with a Matrix : drawBitmap(bitmap, matrix, paint), then you you need to use that Matrix, or concatenate it to that of the Canvas (in the case it has one).
Then you can finally apply that matrix to the center of the matrix using Matrix.mapPoints.
Something like :
canvas.drawBitmap(bitmap, bitmap_transform, paint);
Matrix full_transform = new Matrix(canvas.getMatrix());
full_transform.postConcat(bitmap_transform);
float[] center = new float[] {bitmap.getHeight()/2.0, bitmap.getWidth()/2.0};
full_transform.mapPoints(center);
Alternatively, if you apply transformations to your bitmap without a matrix, you can use the full_transform.postRotate, full_transform.postScale, etc with the same values. In particular, if you draw your bitmap with drawBitmap(bitmap, left, top, paint) then you need to do a full_transform.postTranslate(left, top).
If you're looking for the "easiest" way then just sticking with the translate rotate and scale functions would solve the problem. The reason that those were developed was so developers wouldn't have to do vector calculus for simple animations. Also the only value you would have to actually calculate in that sense it is the translate value after you take into account the original coordinates.
I want to show a sequence of animation(background Transparent) by using a spritesheet (generated by Texturepacker). is there any other engine(way) to show sprite sheet animation other than AndEngine?
If you're drawing the bitmap using canvas you can call
public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
The bitmap is the spritesheet, the src Rect would be the individual sprite you would wish to show from the spritesheet. So if your spritesheet is a 100x100 bitmap of 16 25x25 px sprites you would use a rect of 0,0,25,25 to draw the first frame.
The dst Rect is the actual x/y coordinates and dimension of drawn sprite onto the canvas. Note you're able to change the original sprite dimensions and the canvas with automatically scale the sprite for you.
Now to animate the spritesheet all you need is some code to change the src Rect every time the frame index should increment.
I am attempting to rotate, scale, and translate an image for drawing on a Canvas. However, the order is proving to be troublesome and I am having trouble getting everything to line up correctly.
Matrix matrix = new Matrix();
//matrix.postRotate(90f);
matrix.postScale(scaleFactor, scaleFactor);
matrix.postTranslate(screenCoords.x - scaleWidth/2, screenCoords.y
- scaleHeight/2);
c.drawBitmap(blackJackBM, matrix, this.mPaint);
The scaling and translate works correctly in this instance, however un-commenting the rotation code will cause the image to be offset, in this case, to the left of where it should be drawing. Any ideas?
postRotate(float) rotates the matrix from its upper left point. Use postRotate(float, centerX, centerY) instead.