How can I rotate a bitmap (not a view or canvas) around its center point when the user touches it and drags it?
I have tried loads of examples on stack overflow and none appear to work.
So far I have:
double r = Math.atan2(posX - dial.getWidth() / 2, dial.getHeight() / 2 - posY);
rotation = (int) Math.toDegrees(r);
Create Matrix then set rotate via setRotate(degrees). Then use this matrix when creating new Bitmap: Bitmap.createBitmap(..)
Related
I'm hoping someone can help me out. I'm making an image manipulation app, and I found I needed a better way to load in large images.
My plan, is to iterate through "hypothetical" pixels of an image (a "for loop" that covers width/height of the base image, so each iteration represents a pixel), scale/translate/rotate that pixels position relative to the view, then use this information to determine which pixels are being displayed in the view itself, then use a combination of BitmapRegionDecoder and BitmapFactory.Options to load in only the section of image that the output actually needs rather than a full (even if scaled) image.
So far I seem to have covered scale of the image and translation properly, but I can't seem to figure out how to calculate rotation. Since it's not a real Bitmap pixel I can't use Matrix.rotate =( Here is the image translations in the onDraw of the view, imgPosX and imgPosY hold the center point of the image:
m.setTranslate(-userImage.getWidth() / 2.0f, -userImage.getHeight() / 2.0f);
m.postScale(curScale, curScale);
m.postRotate(angle);
m.postTranslate(imgPosX, imgPosY);
mCanvas.drawBitmap(userImage.get(), m, paint);
and here is the math so far of how I'm trying to determine if an images pixel is on the screen:
for(int j = 0;j < imageHeight;j++) {
for(int i = 0;i < imageWidth;i++) {
//image starts completely center in view, assume image is original size for simplicity
//this is the original starting position for each pixel
int x = Math.round(((float) viewSizeWidth / 2.0f) - ((float) newImageWidth / 2.0f) + i);
int y = Math.round(((float) viewSizeHeight / 2.0f) - ((float) newImageHeight / 2.0f) + j);
//first we scale the pixel here, easy operation
x = Math.round(x * imageScale);
y = Math.round(y * imageScale);
//now we translate, we do this by determining how many pixels
//our images x/y coordinates have differed from it's original
//starting point, imgPosX and imgPosY in the view start in center
//of view
x = x + Math.round((imgPosX - ((float) viewSizeWidth / 2.0f)));
y = y + Math.round((imgPosY - ((float) viewSizeHeight / 2.0f)));
//TODO need rotation here
}
}
so, assuming my math up until rotation is correct (probably not but it appears to be working so far), how would I then calculate the rotation from that pixels position? I've tried other similar questions like:
Link 1
Link 2
Link 3
without using rotation the pixels I expect to actually be on the screen are represented (I made text file that outputs the results in 1's and 0's so I can have a visual representation of whats on the screen), but with the formula found in those questions the information isn't what is expected. (Scenario: I've rotated an image so only the top left corner is visible in the view. Using the info from Here to rotate the pixel, I should expect to see a triangular set of 1's in the upper left corner of the output file, but that's not the case)
So, how would I calculate a a pixels position after rotation without using the Android matrix? But still get the same results.
And if I've just messed it up entirely my apologies =( Any help would be appreciated, this project has gone on for so long and I want to finally be done lol
If you need any more information I will provide as much as I possibly can =) Thank you for your time
I realize this question is particularly difficult so I will be posting a bounty as soon as SO allows.
You do not need to create your own Matrix, use the existing one.
http://developer.android.com/reference/android/graphics/Matrix.html
You can map bitmap coordinates to screen coordinates by using
float[] coords = {x, y};
m.mapPoints(coords);
float sx = coords[0];
float sy = coords[1];
If you want to map screen to bitmap coordinates, you can create the inverse matrix
Matrix inverse = new Matrix(m);
inverse.inverse();
inverse.mapPoints(...)
I think your overall approach is going to be slow, as doing the pixel manipulation on the CU from Java has a lot of overhead. When drawing bitmaps normally, the pixel manipulation is done on the GPU.
I have rotated a dial around its center with the helop from the link below:
http://mobile.tutsplus.com/tutorials/android/android-sdk-creating-a-rotating-dialer/
Now I have an icon beside the dialer and I need to rotate it around the dialer, along with the dialer in a circular path.
private void rotateLogo(float degrees){
Matrix nMatrix = new Matrix();
Bitmap peopleOrg = BitmapFactory.decodeResource(getResources(), R.drawable.peoplelogo);
float translateX = dialerWidth / 2 - dialerWidth / 2;
float translateY = dialerHeight / 2 - dialerWidth / 2;
nMatrix.preTranslate(-turntable.getWidth()/2, -turntable.getHeight()/2);
nMatrix.postRotate(degrees, translateX, translateY);
nMatrix.postTranslate(turntable.getWidth()/2, turntable.getHeight()/2);
Bitmap peopleScale = Bitmap.createBitmap(peopleOrg, 0, 0, peopleOrg.getWidth(), peopleOrg.getHeight(), nMatrix, true);
peopleLogo.setImageBitmap(peopleScale);
peopleLogo.setImageMatrix(nMatrix);
}
This just causes the image to rotate around its own center and not around the dialer's center point.
I cant find out where i am wrong :(
Updates
I basically need the logo to move in a circular path and be a clickable view.
Tried using rotateAnim but the view doesnt animate and i have trouble getting the onclick event.
Would like any help that can rotate the same using matrices
Try only rotate with peopleOrg width and height.
nMatrix.postRotate(degrees, peopleOrg.getWidth()/2, peopleOrg.getHeight()/2);
Update :
Now that you let me know that your logo should be a clickable view, merging the logo image with your dialer is not applicable. To rotate the logo view around the center of dialer you should be actually calculating the (top,left) point for your logo view and moving it around, than just rotating it.
Use sine and cosine functions to get the point on the circumference of an imaginary circle for drawing your logo view.
This post will help you with calculations : How do I calculate a point on a circle’s circumference?
How can I rotate a bitmap (not a view or canvas) around its center point when the user touches it and drags it?
I have tried loads of examples on stack overflow and none appear to work.
So far I have:
double r = Math.atan2(posX - dial.getWidth() / 2, dial.getHeight() / 2 - posY);
rotation = (int) Math.toDegrees(r);
Create Matrix then set rotate via setRotate(degrees). Then use this matrix when creating new Bitmap: Bitmap.createBitmap(..)
How can I rotate a bitmap (not a view or canvas) around its center point when the user touches it and drags it?
I have tried loads of examples on stack overflow and none appear to work.
So far I have:
double r = Math.atan2(posX - dial.getWidth() / 2, dial.getHeight() / 2 - posY);
rotation = (int) Math.toDegrees(r);
Create Matrix then set rotate via setRotate(degrees). Then use this matrix when creating new Bitmap: Bitmap.createBitmap(..)
I am trying to rotate image in image view coresponding with touch to fix pivote pint of image . i have seen many of example but i dont clear with all of it .somebody have idea ..how can do it this this ?
Since there is no code or details provided about where the bitmap is drawn i assume its at the center of the screen. You can rotate the canvas on center point like this
double rotationAngleRadians = Math.atan2(currentX - centerX, centerY - currentY);
rotationAngleDegrees = (int) Math.toDegrees(rotationAngleRadians );
canvas.rotate(rotationAngleDegrees , centerX, centerY);