Reputation: 77
I'm making a game where some objects rotate to face what they're shooting at. There's a delay in between shooting and I want the object to keep facing where it is until it shoots again. I know how to load images and I know how to rotate them using AffineTransform. But with this I need to calculate the rotate every time the object gets drawn.
So my question is how can I rotate an image and save the result into a new image that would get displayed?
Upvotes: 3
Views: 3205
Reputation: 5818
Affline transform only works with perfect squares. The following code is used to take any rectangle image and rotate it correctly. To do this it chooses a center point that is half the greater length and tricks the library to think the image is a perfect square, then it does the rotation and tells the library where to find the correct top left point. The special cases in each orientation happen when the extra image that doesn't exist is either on the left or on top of the image being rotated. In both cases the point is adjusted by the difference in the longer side and the shorter side to get the point at the correct top left corner of the image. NOTE: the x and y axes also rotate with the image so where width > height the adjustments always happen on the y axis and where the height > width the adjustments happen on the x axis.
private BufferedImage rotate(BufferedImage image, double _theta, int _thetaInDegrees) {
AffineTransform xform = new AffineTransform();
if (image.getWidth() > image.getHeight()) {
xform.setToTranslation(0.5 * image.getWidth(), 0.5 * image.getWidth());
xform.rotate(_theta);
int diff = image.getWidth() - image.getHeight();
switch (_thetaInDegrees) {
case 90:
xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth() + diff);
break;
case 180:
xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth() + diff);
break;
default:
xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth());
break;
}
} else if (image.getHeight() > image.getWidth()) {
xform.setToTranslation(0.5 * image.getHeight(), 0.5 * image.getHeight());
xform.rotate(_theta);
int diff = image.getHeight() - image.getWidth();
switch (_thetaInDegrees) {
case 180:
xform.translate(-0.5 * image.getHeight() + diff, -0.5 * image.getHeight());
break;
case 270:
xform.translate(-0.5 * image.getHeight() + diff, -0.5 * image.getHeight());
break;
default:
xform.translate(-0.5 * image.getHeight(), -0.5 * image.getHeight());
break;
}
} else {
xform.setToTranslation(0.5 * image.getWidth(), 0.5 * image.getHeight());
xform.rotate(_theta);
xform.translate(-0.5 * image.getHeight(), -0.5 * image.getWidth());
}
AffineTransformOp op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR);
return op.filter(image, null);
}
Upvotes: 3
Reputation: 59576
Try something like this to clone images:
BufferedImage source = new BufferedImage(50, 10, BufferedImage.TYPE_4BYTE_ABGR);
BufferedImage target = new BufferedImage(50, 10, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D tg = target.createGraphics();
AffineTransform at = new AffineTransform();
at.rotate(2);
tg.drawImage(source, at, null);
P.S.: Ignore my previous answer, I misread the question. Sorry.
Upvotes: 1
Reputation: 420951
how can I rotate an image and save the result into a new image that would get displayed?
Create a new BufferedImage
. Get hold of a Graphics
object (through BufferedImage.getGraphics()
. Paint the rotated image onto this buffered image, and save the image in an array or a map based on its rotation (so that it easy to look it up when you need it).
Upvotes: 3