旋转Java中的缓冲图像 [英] Rotate a buffered image in Java

查看:58
本文介绍了旋转Java中的缓冲图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试旋转Java中的缓冲图像.这是我正在使用的代码:

I am trying to rotate a buffered image in java. Here is the code I am using:

public static BufferedImage rotate(BufferedImage bimg, double angle){
    int w = bimg.getWidth();    
    int h = bimg.getHeight();
    Graphics2D graphic = bimg.createGraphics();
    graphic.rotate(Math.toRadians(angle), w/2, h/2);
    graphic.drawImage(bimg, null, 0, 0);
    graphic.dispose();
    return bimg;
}

我已经看过许多关于此主题的堆栈溢出问题和答案,但无法弄清为什么在尝试旋转图像时会像原来那样被切碎.这是显示加载的图像的示例: 已加载图像

I have looked a numerous stack overflow questions and answers on this topic and not been able to figure out why the image is chopped up the way it is when I try to rotate it. Here is an example showing a loaded image: loaded image

单击旋转按钮后,将使用缓冲的图像和角度90.0调用上述函数: 切碎的图像

After I click the rotate button which calls the above function with the buffered image and a 90.0 for the angle: chopped up image

有人可以帮助我了解发生了什么以及如何解决吗?

Can someone help me understand what is happening and how to fix it?

谢谢!

推荐答案

与往常一样,Internet可以进行救援.因此,这是我从其他资源/帖子/博客中获取的一些代码,它们将返回一个新图像,该图像的大小将包含旋转后的图像

As always, the Internet to the rescue. So, this is some code which I hobbled together from other resources/post/blogs which will return a new image which is sized so it will contain the rotated image

public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) {

            double rads = Math.toRadians(angle);
            double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads));
            int w = img.getWidth();
            int h = img.getHeight();
            int newWidth = (int) Math.floor(w * cos + h * sin);
            int newHeight = (int) Math.floor(h * cos + w * sin);

            BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = rotated.createGraphics();
            AffineTransform at = new AffineTransform();
            at.translate((newWidth - w) / 2, (newHeight - h) / 2);

            int x = w / 2;
            int y = h / 2;

            at.rotate(rads, x, y);
            g2d.setTransform(at);
            g2d.drawImage(img, 0, 0, this);
            g2d.setColor(Color.RED);
            g2d.drawRect(0, 0, newWidth - 1, newHeight - 1);
            g2d.dispose();

            return rotated;
        }

已更新

因此,使用此PNG:

还有此代码...

package javaapplication1.pkg040;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage master;
        private BufferedImage rotated;

        public TestPane() {
            try {
                master = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/Miho_Small.png"));
                rotated = rotateImageByDegrees(master, 0.0);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            Timer timer = new Timer(40, new ActionListener() {
                private double angle = 0;
                private double delta = 1.0;

                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += delta;
                    rotated = rotateImageByDegrees(master, angle);
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return master == null
                         ? new Dimension(200, 200)
                         : new Dimension(master.getWidth(), master.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (rotated != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - rotated.getWidth()) / 2;
                int y = (getHeight() - rotated.getHeight()) / 2;
                g2d.drawImage(rotated, x, y, this);
                g2d.dispose();
            }
        }

        public BufferedImage rotateImageByDegrees(BufferedImage img, double angle) {

            double rads = Math.toRadians(angle);
            double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads));
            int w = img.getWidth();
            int h = img.getHeight();
            int newWidth = (int) Math.floor(w * cos + h * sin);
            int newHeight = (int) Math.floor(h * cos + w * sin);

            BufferedImage rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = rotated.createGraphics();
            AffineTransform at = new AffineTransform();
            at.translate((newWidth - w) / 2, (newHeight - h) / 2);

            int x = w / 2;
            int y = h / 2;

            at.rotate(rads, x, y);
            g2d.setTransform(at);
            g2d.drawImage(img, 0, 0, this);
            g2d.dispose();

            return rotated;
        }
    }

}

我可以生成类似...

I can generate something like...

这篇关于旋转Java中的缓冲图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆