【问题标题】:Java rotate image turns part of background blackJava旋转图像将部分背景变为黑色
【发布时间】:2015-12-07 20:59:54
【问题描述】:

当我尝试旋转图像时,背景的一部分似乎变黑(我的图像是透明的)

Background white
Part of background turns black

这是旋转图像的代码:

public BufferedImage rotate(int height, int width, BufferedImage originalImg, int angle) {
    BufferedImage rotateImage = null;
    try {
        rotateImage = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
        AffineTransform a90 = AffineTransform.getRotateInstance(Math.toRadians(angle), height / 2, width / 2);
        AffineTransformOp op90 = new AffineTransformOp(a90, AffineTransformOp.TYPE_BILINEAR);
        op90.filter(originalImg, rotateImage);
    }
    catch (Exception e) {
        System.err.println(e);
    }
    return rotateImage;
}

【问题讨论】:

  • 所有接受宽度和高度的 API 都将宽度参数放在高度参数之前。我不确定你是否故意改变了它们。无论如何,BufferedImage 构造函数需要宽度后跟高度,而 AffineTransform.getRotateInstance 方法需要 X 坐标后跟 Y 坐标。
  • 好吧,我的图片都是方形的,所以变化不大,getRotateInstance 需要一个锚点来旋转,所以我发送了图片中间的高度/2 和宽度/2
  • 这与我有关:BufferedImage.TYPE_INT_RGB。不应该是BufferedImage.TYPE_INT_ARGB吗?你有透明度,这意味着你需要 alpha。
  • 有效!非常感谢,我没看到

标签: java swing image-rotation affinetransform rgba


【解决方案1】:

所以,我下载了你的“原始”图像(不是方形的),将它修改为方形,运行你的代码,得到一个java.awt.image.ImagingOpException: Unable to transform src image 异常,将BufferedImage.TYPE_INT_RGB 更改为BufferedImage.TYPE_INT_ARGB 并得到...

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Main {

    public static void main(String[] args) {
        try {
            BufferedImage img = ImageIO.read(Main.class.getResource("/Block.jpg"));
            BufferedImage rotate = rotate(img.getHeight(), img.getWidth(), img, 90);

            JPanel panel = new JPanel();
            panel.add(new JLabel(new ImageIcon(img)));
            panel.add(new JLabel(new ImageIcon(rotate)));

            JOptionPane.showMessageDialog(null, panel);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static BufferedImage rotate(int height, int width, BufferedImage originalImg, int angle) {
        BufferedImage rotateImage = null;
        try {
            rotateImage = new BufferedImage(height, width, BufferedImage.TYPE_INT_ARGB);
            AffineTransform a90 = AffineTransform.getRotateInstance(Math.toRadians(angle), height / 2, width / 2);
            AffineTransformOp op90 = new AffineTransformOp(a90, AffineTransformOp.TYPE_BILINEAR);
            op90.filter(originalImg, rotateImage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rotateImage;
    }

}

我的“直觉”感觉是也要修改 rotate 方法,因为它不应该需要 widthheight 值;

public static BufferedImage rotate(BufferedImage originalImg, int angle) {
    BufferedImage rotateImage = null;
    try {
        rotateImage = new BufferedImage(originalImg.getWidth(), originalImg.getHeight(), BufferedImage.TYPE_INT_ARGB);
        AffineTransform a90 = AffineTransform.getRotateInstance(Math.toRadians(angle), originalImg.getWidth() / 2, originalImg.getHeight() / 2);
        AffineTransformOp op90 = new AffineTransformOp(a90, AffineTransformOp.TYPE_BILINEAR);
        op90.filter(originalImg, rotateImage);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rotateImage;
}

它应该直接使用原始图像的尺寸。这将突出显示图像中可能存在的错误。这也假设您只想将图像旋转 90 度

【讨论】:

  • 非常感谢!我做了你的改变,它工作得很好
最近更新 更多