@Override public Rectangle2D getBounds2D(final BufferedImage src) { return delegate.getBounds2D(src); }
@Override public Rectangle2D getBounds2D(final Raster src) { return delegate.getBounds2D(src); }
@Override public Rectangle2D getBounds2D(final Raster src) { return delegate.getBounds2D(src); }
@Override public Rectangle2D getBounds2D(final BufferedImage src) { return delegate.getBounds2D(src); }
// Read the image and set angle (as before) BufferedImage myImage = ImageIO.read(...)); double angle = 12; // Create AffineTransformOp to do the calculation AffineTransform rotation = AffineTransform.getRotateInstance(angle); AffineTransformOp op = new AffineTransformOp(rotation, null); Rectangle bounds = op.getBounds2D(myImage).getBounds(); // Correctly rounded bounds // You can now use bounds.x, bounds.y, bounds.width and bounds.height as you like. // Example: widthFinal = bounds.width; heightFinal = bounds.height;
public static BufferedImage rotateImage(BufferedImage image, double theta) { int degrees = (int) Math.abs(Math.toDegrees(theta)); double xCenter = image.getWidth() / 2; double yCenter = image.getHeight() / 2; AffineTransform rotateTransform = AffineTransform.getRotateInstance(-theta, xCenter, yCenter); // Translation adjustments so image still centered after rotate width/height changes if (image.getHeight() != image.getWidth() && degrees != 180 && degrees != 0) { Point2D origin = new Point2D.Double(0.0, 0.0); origin = rotateTransform.transform(origin, null); double yTranslate = origin.getY(); Point2D yMax = new Point2D.Double(0, image.getHeight()); yMax = rotateTransform.transform(yMax, null); double xTranslate = yMax.getX(); AffineTransform translationAdjustment = AffineTransform.getTranslateInstance(-xTranslate, -yTranslate); rotateTransform.preConcatenate(translationAdjustment); } AffineTransformOp op = new AffineTransformOp(rotateTransform, AffineTransformOp.TYPE_BILINEAR); // Have to recopy image because of JDK bug #4723021, AffineTransformationOp throwing exception sometimes image = copyImage(image, BufferedImage.TYPE_INT_ARGB); // Need to create filter dest image ourselves since AffineTransformOp's own dest image creation // throws exceptions in some cases. Rectangle bounds = op.getBounds2D(image).getBounds(); BufferedImage finalImage = new BufferedImage((int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB); return op.filter(image, finalImage); }