Currently I am using this code (which I found here) to rotate images in Java. The code works well, but I am not satisfied with the quality of the rotated image.
How can I improve it? Do it need a separate library that?
public static BufferedImage rotate(BufferedImage image, float angle) { float radianAngle = (float) Math.toRadians(angle) ; float sin = (float) Math.abs(Math.sin(radianAngle)); float cos = (float) Math.abs(Math.cos(radianAngle)); int w = image.getWidth() ; int h = image.getHeight(); int neww = (int) Math.round(w * cos + h * sin); int newh = (int) Math.round(h * cos + w * sin); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT); Graphics2D g = result.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.translate((neww-w)/2, (newh-h)/2); g.rotate(radianAngle, w/2, h/2); g.drawRenderedImage(image, null); g.dispose(); return result; }
Advertisement
Answer
You should set RenderingHints.KEY_INTERPOLATION
and RenderingHints.KEY_RENDERING
as well.
Here is the complete working code:
public static BufferedImage rotate(BufferedImage image, float angle) { float radianAngle = (float) Math.toRadians(angle) ; float sin = (float) Math.abs(Math.sin(radianAngle)); float cos = (float) Math.abs(Math.cos(radianAngle)); int w = image.getWidth() ; int h = image.getHeight(); int neww = (int) Math.round(w * cos + h * sin); int newh = (int) Math.round(h * cos + w * sin); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT); Graphics2D g = result.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) ; // this will further improve the quality g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); AffineTransform at = AffineTransform.getTranslateInstance((neww-w)/2, (newh-h)/2); at.rotate(radianAngle, w/2, h/2); g.drawRenderedImage(image, at); g.dispose(); return result; }