I wanted to crop an image after rotating it, and couldn’t figure out a way to do this using the Java2D AffineTransform (and not have it wreak havok with the rest of what was on the screen.
Maybe there is a way to do this and I just reinvented a wheel for nothing. But at least I finally learned something about basic 2D Transforms (and the matrix & vector math underlying).
So, below is some code that can rotate an image. First a demo graphic or two:
http://hexara.com/Images/Strawberries.JPG
Graphic for Apo!
http://hexara.com/Images/TiltedSheep.JPG
Code is here:
http://pastebin.java-gaming.org/55c3f863a26
The code: first get it working, now it needs improvement. The biggest question I have is the way I interpolate the new pixel values. As I generate the new locations for the original pixels, I store the distance to the surrounding four points (or less, if one is on the edge). Then, when determining the color of the new pixels, I take the closest three and use a weighted average based on their distances. This seems a little dubious as the the triangles are not equilateral, so the angles should also be taken into consideration. However, they are right triangles and thus the corners are pretty well spread out, and visually it seems to work pretty well.
I tried using just the closest point, and by calculating the weighted average using the square of the distance, but both shortcuts were considerably more jaggy. I am assuming someone has come up with a better way to do the interpolation of the new values, and would love to learn about it.
To use the code, create an ImageRotator object, then call the rotate() method, with three parameters (1) image to be rotated (2) radians of rotation (3) a boolean that is false if the graphic has no alpha (is a normal jpeg, for example) or true if there is alpha data that needs to be part of the interpolation. The method returns a BufferedImage of the rotated graphic.