Rotate BufferedImage with transparent background

后端 未结 1 581
天涯浪人
天涯浪人 2021-01-25 15:27

I have an image with transparent background. I\'d like to rotate this image to a specific angle and keep the transparent background for the resulting image. For this purpose I u

相关标签:
1条回答
  • 2021-01-25 16:01

    I'm a bit puzzled about the behavior of Graphics.drawImage(). Maybe somebody else can comment about it.

    However, Graphics2D.drawRenderedImage() works a treat. It takes an AffineTransform to control the rotation. The below example nicely works. You probably have additional requirement about the final image size and the location of the rotated image.

    import javax.imageio.ImageIO;
    import java.awt.Graphics2D;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.File;
    
    public class ImageRotation {
    
        public static void main(String[] args) {
            ImageRotation rotation = new ImageRotation();
            rotation.rotate("input.png", 45, "output.png");
        }
    
        public void rotate(String inputImageFilename, double angle, String outputImageFilename) {
    
            try {
                BufferedImage inputImage = ImageIO.read(new File(inputImageFilename));
                BufferedImage outputImage = rotateImage(inputImage, angle);
                ImageIO.write(outputImage, "PNG", new File(outputImageFilename));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        private BufferedImage rotateImage(BufferedImage sourceImage, double angle) {
            int width = sourceImage.getWidth();
            int height = sourceImage.getHeight();
            BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = destImage.createGraphics();
    
            AffineTransform transform = new AffineTransform();
            transform.rotate(angle / 180 * Math.PI, width / 2 , height / 2);
            g2d.drawRenderedImage(sourceImage, transform);
    
            g2d.dispose();
            return destImage;
        }
    }
    

    Update

    While the above code works for most PNGs, it does not work for the image that alexanoid is using. I've analyzed the image:

    • It's a grayscale image without a color palette (PNG color type 0) .
    • It uses simple transparency with a 2 byte long tRNS chunk.

    As far as I can tell that's perfectly legal. However, ImageIO does not implement this combination. If the image has no palette, it simply ignores the tRNS chunk and therefore ignores the transparency information. That's most likely a bug.

    You basically have two options now:

    1. Look for an alternative library to read PNG files.
    2. Fix the transparency after you have read the PNG file. This only works if know that the image used the particular problematic format.

    Input and output for working PNG files

    Input image:

    Ouptput Image:

    0 讨论(0)
提交回复
热议问题