旋转 BufferedImage 实例

发布于 2024-10-16 14:03:14 字数 593 浏览 2 评论 0原文

我在显示旋转的 BufferedImage 时遇到问题。我认为旋转工作得很好,但我实际上无法将其绘制到屏幕上。我的代码:

Class extends JPanel {
    BufferedImage img;
    int rotation = 0;

    public void paintComponent(Graphics g) {
        g.clearRect(0, 0, getWidth(), getHeight());
        img2d = img.createGraphics();
        img2d.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
        g.drawImage(img, imgx, imgy, null);
        this.repaint();
    }
}

这对我不起作用。我找不到任何方法将旋转的 img2d 绘制到 g 上。

编辑:我有多个对象被绘制到 g 上,所以我无法旋转它。我需要能够单独旋转事物。

I am having trouble getting a rotated BufferedImage to display. I think the rotation is working just fine, but I can't actually draw it to the screen. My code:

Class extends JPanel {
    BufferedImage img;
    int rotation = 0;

    public void paintComponent(Graphics g) {
        g.clearRect(0, 0, getWidth(), getHeight());
        img2d = img.createGraphics();
        img2d.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
        g.drawImage(img, imgx, imgy, null);
        this.repaint();
    }
}

This is not working for me. I could not find any way to draw the rotated img2d onto g.

EDIT: I have multiple objects that are being drawn onto g, so I can't rotate that. I need to be able to rotate things individually.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

太阳公公是暖光 2024-10-23 14:03:14

也许您应该尝试像这样使用 AffineTransform

AffineTransform transform = new AffineTransform();
transform.rotate(radians, bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);

希望这会有所帮助。

Maybe you should try using AffineTransform like this:

AffineTransform transform = new AffineTransform();
transform.rotate(radians, bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);

Hope this helps.

乖乖公主 2024-10-23 14:03:14

我会使用 Graphics2D.drawImage(image, affinetranform, imageobserver)

下面的代码示例将图像旋转和平移到组件的中心。这是结果的屏幕截图:

screenshot

public static void main(String[] args) throws IOException {
    JFrame frame = new JFrame("Test");

    frame.add(new JComponent() {
        BufferedImage image = ImageIO.read(
                new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // create the transform, note that the transformations happen
            // in reversed order (so check them backwards)
            AffineTransform at = new AffineTransform();

            // 4. translate it to the center of the component
            at.translate(getWidth() / 2, getHeight() / 2);

            // 3. do the actual rotation
            at.rotate(Math.PI / 4);

            // 2. just a scale because this image is big
            at.scale(0.5, 0.5);

            // 1. translate the object so that you rotate it around the 
            //    center (easier :))
            at.translate(-image.getWidth() / 2, -image.getHeight() / 2);

            // draw the image
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(image, at, null);

            // continue drawing other stuff (non-transformed)
            //...
        }
    });

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setVisible(true);
}

I would use Graphics2D.drawImage(image, affinetranform, imageobserver).

The code example below rotates and translates an image to the center of the component. This is a screenshot of the result:

screenshot

public static void main(String[] args) throws IOException {
    JFrame frame = new JFrame("Test");

    frame.add(new JComponent() {
        BufferedImage image = ImageIO.read(
                new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // create the transform, note that the transformations happen
            // in reversed order (so check them backwards)
            AffineTransform at = new AffineTransform();

            // 4. translate it to the center of the component
            at.translate(getWidth() / 2, getHeight() / 2);

            // 3. do the actual rotation
            at.rotate(Math.PI / 4);

            // 2. just a scale because this image is big
            at.scale(0.5, 0.5);

            // 1. translate the object so that you rotate it around the 
            //    center (easier :))
            at.translate(-image.getWidth() / 2, -image.getHeight() / 2);

            // draw the image
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(image, at, null);

            // continue drawing other stuff (non-transformed)
            //...
        }
    });

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setVisible(true);
}
掩饰不了的爱 2024-10-23 14:03:14

您正在旋转图形以绘制到图像中,而不是图像中。这就是为什么你看不到效果。将旋转应用到您正在绘制的图形上,它将绘制旋转的图像:

public void paintComponent(Graphics g) {
    g.clearRect(0, 0, getWidth(), getHeight());
    g.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
    g.drawImage(img, imgx, imgy, null);
    this.repaint();
}

这可能不会完全绘制出您期望的内容,旋转将围绕坐标原点旋转。对于要绕其中心旋转的图像,您需要在旋转之前应用坐标平移,例如:

g.translate(imgx >> 1, imgy >> 1);

Graphics2D 教程 还有更多示例。

You are rotating the graphics for drawing into your image, not the image. Thats why you see no effect. Apply the rotation to the graphics you are painting on and it will draw the image rotated:

public void paintComponent(Graphics g) {
    g.clearRect(0, 0, getWidth(), getHeight());
    g.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
    g.drawImage(img, imgx, imgy, null);
    this.repaint();
}

This will probably not draw entirely what you expect, the rotation will revolve around the coordinate origin. For the image to be rotate around its center you need to apply a coordinate translation before the rotation, for example:

g.translate(imgx >> 1, imgy >> 1);

The Graphics2D Tutorial has some more examples.

末蓝 2024-10-23 14:03:14

我知道这个问题很老了,但我想出了一个具有一些优点的解决方案:

  • 创建正确尺寸的图像。
  • 正确的偏移量。
  • 不会不必要地旋转 0° 或 360°。
  • 适用于负角度(例如-90°)。
  • 当输入为 BufferedImage.TYPE_CUSTOM 时有效。

事实上,假设该角度是90°的倍数。唯一可能需要的改进是使用 Enum 表示 angle 而不仅仅是 int

这是我的代码:

public static BufferedImage rotateBufferedImage(BufferedImage img, int angle) {
    if (angle < 0) {
        angle = 360 + (angle % 360);
    }
    angle %= 360;
    if (angle == 0) {
        return img;
    }
    final boolean r180 = angle == 180;
    if (angle != 90 && !r180 && angle != 270)
        throw new IllegalArgumentException("Invalid angle.");
    final int w = r180 ? img.getWidth() : img.getHeight();
    final int h = r180 ? img.getHeight() : img.getWidth();
    final int type = img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType();
    final BufferedImage rotated = new BufferedImage(w, h, type);
    final Graphics2D graphic = rotated.createGraphics();
    graphic.rotate(Math.toRadians(angle), w / 2d, h / 2d);
    final int offset = r180 ? 0 : (w - h) / 2;
    graphic.drawImage(img, null, offset, -offset);
    graphic.dispose();
    return rotated;
}
public static BufferedImage rotateBufferedImage(String img, int angle) throws IOException {
    return rotateBufferedImage(Paths.get(img), angle);
}
public static BufferedImage rotateBufferedImage(Path img, int angle) throws IOException {
    return rotateBufferedImage(ImageIO.read(img.toFile()), angle);
}

I know this question is old but I came up with a solution that has some advantages:

  • creates image of correct size.
  • correct offset.
  • does not unnecessarily rotate by 0° or 360°.
  • works for negative angles (e.g. -90°).
  • works when input is BufferedImage.TYPE_CUSTOM.

As it is, it is assumed that the angle is a multiple of 90°. The only improvement that one might need is to use an Enum for angle instead of just int.

Here's my code:

public static BufferedImage rotateBufferedImage(BufferedImage img, int angle) {
    if (angle < 0) {
        angle = 360 + (angle % 360);
    }
    angle %= 360;
    if (angle == 0) {
        return img;
    }
    final boolean r180 = angle == 180;
    if (angle != 90 && !r180 && angle != 270)
        throw new IllegalArgumentException("Invalid angle.");
    final int w = r180 ? img.getWidth() : img.getHeight();
    final int h = r180 ? img.getHeight() : img.getWidth();
    final int type = img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType();
    final BufferedImage rotated = new BufferedImage(w, h, type);
    final Graphics2D graphic = rotated.createGraphics();
    graphic.rotate(Math.toRadians(angle), w / 2d, h / 2d);
    final int offset = r180 ? 0 : (w - h) / 2;
    graphic.drawImage(img, null, offset, -offset);
    graphic.dispose();
    return rotated;
}
public static BufferedImage rotateBufferedImage(String img, int angle) throws IOException {
    return rotateBufferedImage(Paths.get(img), angle);
}
public static BufferedImage rotateBufferedImage(Path img, int angle) throws IOException {
    return rotateBufferedImage(ImageIO.read(img.toFile()), angle);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文