I would like to display a transperent PNG of a "light" line shape according to user's sliding path.
I'd like to make similar effect like Fruit Ninja has, and leave a track after user slides his finger.
I already have the x,y points of his finger - using onTouch method, and checking the x,y on MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP but how do i draw an image that will be tilted and displayed at those positions? all i know is to add padding/margin to an image, not how to place it using x,y, or how to rotate it..
For positioning and rotating use a canvas (getSurfaceHolder().lockCanvas()) and draw inside it using drawBitmap.
public void drawBitmap (Bitmap bitmap, Matrix mtx, Rect dst, Paint paint)
the matrix can include the rotation:
Matrix mtx = new Matrix();
mtx.postRotate(90);
You might want to se the code from API demos, FingerPaint.
Related
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 got success in implementing a pinch zoom in/out and drag/drop functionality in images on the canvas.
Now what I want is re-sizing, that images like below link that based on iPhone App
How to change shape of an image using iPhone SDK?
So how can I achieve that kind of functionality in Android ?
Basically you need to invalidate the image and re-draw on the canvas from the beginning ::
img=(ImageView)findViewById(R.id.yourimageidfromxml);
img.onTouchEvent(MotionEvent me)
{
int X=me.getX();
int Y=me.getY();
img.invalidate();
img.repaint(X,Y);
}
void paint(int X,int Y)
{
img.setWidth(X);
img.setHeight(Y);
}
Scaling image will transform using repaint on canvas from the beginning
If by re-sizing you are referring to "stretching" the Bitmap on the vertical and horizontal plane then you simply modify the rect that the shape (eg. oval) is being drawn into.
For example:
This is your original shape of an oval:
canvas.drawOval(new Rect(0,0,100,100), bluePaint);
This is the same oval, just stretched (resized) on the horizontal plane:
canvas.drawOval(new Rect(0,0,200,100), bluePaint);
I hope this helps.
There are two options, both involving a custom view. The first is to create a custom view that fills your "canvas". You can keep track of 8 blue and 1 green circles in the view as Rect objects. Override onTouchEvent(MotionEvent) and then check if motion events are in any of your controls and update them accordingly (I'm simplifying things a bit here :)). From your onTouchEvent you would call invalidate(). You're onDraw(Canvas) can then handle drawing the controls and update the image according to how your controls have changed since the last call to onDraw.
The other option is to do something similar, but with a view that only encapsulates the circle and controls, meaning that moving the view around would require a container that will let the view change it's layout parameters. Doing this, your onTouchEvent method would need to trigger an invalidate with that layout view because it would need to recalculate the size and position of your view. This would definitely be harder but depending on what you are trying to achieve working with individual views may be better than maintaining representations of your circles in code in a single view.
The resizing of the image can be achieved by using a simple ImageView with scaleType "fitXY".
You have to add the blue resize handles yourself.
Changing the rotation of the image (green handle) can be achieved by using:
public static Bitmap rotate(Bitmap src, float degree) {
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
// return new bitmap rotated using matrix
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
}
Source: http://xjaphx.wordpress.com/2011/06/22/image-processing-rotate-image-on-the-fly/
See http://xjaphx.wordpress.com/learning/tutorials/ for more Android Image Processing examples.
How can I rotate an image around it's center point? This rotates it but also moves it:
Matrix mat = new Matrix();
mat.postRotate(45);
Bitmap bMapRotate = Bitmap.createBitmap(dialBM, 0, 0, dialBM.getWidth(),dialBM.getHeight(), mat, true);
dial.setImageBitmap(bMapRotate);
I've checked other examples on this site, but they either fail to work or use canvas, I do not wish to use canvas.
The second and third arguments to postRotate is the x and y pivot point.
mat.postRotate(45, dialBM.getWidth()/2, dialBM.getHeight()/2);
Probably because your matrix rotates around (0,0), and not the middle of your bitmap. You should declare two additional matrices - one for moving the bitmap's center to (0,0) (shift by -getWidth()/2, -getHeight(2)) and one to move the bitmap's center back to (0,0). Multiply the three matrices, and then the result.
I'm implementing a pinching and dragging thing and I'm confused as to how to get the image that I'm affecting to move to it's dragged to location (the scaling is working).
So, in the past I would position the image thusly...
canvas.drawBitmap(img, x,y, paint);
but now that I'm using a matrix I don't see what function in it gets the image over to where I want it to be.
Could someone post a short code snippet of what one needs to do to get the image to move away from 0,0?
TIA
Use postTranslate on your scaling matrix:
scaleMatrix.postTranslate(x, y);
canvas.drawBitmap(img, scaleMatrix, paint);
I have two arrows drawn on my canvas using the canvas.DrawPath(). I'm using canvas.rotate() to rotate, but it is obviously rotating both arrows by the same amount.
Id like to be able to rotate one arrow one way, and rotate the other arrow in a different direction.
Is this possible?
When you use canvas.rotate() you are altering the transformation matrix associated to the canvas, so all what you paint after that will be affected by the current state of the matrix, you have to do the following:
canvas.save(); //Save current canvas matrix state
canvas.rotate(angle);
canvas.DrawPath(); //Draw first arrow
canvas.restore(); //Restore canvas matrix to saved state
canvas.DrawPath(); //Draw second arrow without the rotation