Furykid's answer is great and helped me a lot. But it is not so beautiful. If the image is rectangular, the resulting rotated image may contain some additional black pixels on one side.
I tried a photo of Marty Feldman, the original and the results can be viewed at this link: Martin Feldman rotation test
It's hard to see on a black background, but on any image editing software it's easy to see a small black frame on the right and bottom of the resulting images. This may not be a problem for some, but if it is for you, there is a fixed code (I saved the original as comments for an easier comparison):
public BufferedImage rotateImage(BufferedImage image, int quadrants) { int w0 = image.getWidth(); int h0 = image.getHeight(); /* These are not necessary anymore * int w1 = w0; * int h1 = h0; */ int centerX = w0 / 2; int centerY = h0 / 2; /* This is not necessary anymore * if (quadrants % 2 == 1) { * w1 = h0; * h1 = w0; * } */ //System.out.println("Original dimensions: "+w0+", "+h0); //System.out.println("Rotated dimensions: "+w1+", "+h1); if (quadrants % 4 == 1) { centerX = h0 / 2; centerY = h0 / 2; } else if (quadrants % 4 == 3) { centerX = w0 / 2; centerY = w0 / 2; } //System.out.println("CenterX: "+centerX); //System.out.println("CenterY: "+centerY); AffineTransform affineTransform = new AffineTransform(); affineTransform.setToQuadrantRotation(quadrants, centerX, centerY); AffineTransformOp opRotated = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); /*Old code for comparison //BufferedImage transformedImage = new BufferedImage(w1, h1,image.getType()); //transformedImage = opRotated.filter(image, transformedImage); */ BufferedImage transformedImage = opRotated.filter(image, null); return transformedImage; }
WARNING: Opinion Ahead. I'm not sure why this is happening, but I have an assumption. If you can explain better, edit.
I believe that the reason for this "glitch" is associated with odd sizes. When calculating the dimensions for the new BufferedImage
height of 273 will generate a center of Y 136, for example, when the correct value is 136.5. This can cause the rotation to occur in a small off-center location. However, by sending null
to filter
as the target image, "a BufferedImage
is created with the ColorModel
source", and this seems to work best.
Hemeligur
source share