旋转的BufferedImage内的JPanel(Rotate BufferedImage Insi

2019-08-19 04:24发布

我想旋转BufferedImage和内部显示它JLabel (这是一个内部JPanel )。 当前结果产生白色正方形旋转10度在黑色背景,但图像不存在的正方形内。 我知道myPicture不为空,因为myPicture本身正常显示里面JPanel不旋转时。

下面是代码:

int w = myPicture.getWidth();    

int h = myPicture.getHeight();  

BufferedImage newImage = new BufferedImage(w, h, myPicture.getType());

Graphics2D graphic = newImage.createGraphics();

graphic.rotate(Math.toRadians(10), w/2, h/2);

graphic.drawImage(myPicture, null, 0, 0);

picLabel.setIcon(new ImageIcon(newImage));

Answer 1:

这里没有很多去,但两件事情浮现在脑海中。 这有可能是图像没有在正确的位置上渲染它的旋转后和两个,你不处置的的Graphics ,当你与它(不,我认为它应该有一个效果做背景,但你永远不知道)。

这是一个简单的例子呈现经由结果paintComponent ,但概念是相同的。

它使用AffineTransformation旋转图像。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestRotateImage {

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

    public TestRotateImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

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

    public class TestPane extends JPanel {

        private JSlider slider;
        private BufferedImage image;

        public TestPane() {
            setLayout(new BorderLayout());

            try {
                image = ImageIO.read(new File("/path/to/your/image"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            slider = new JSlider();
            slider.setMinimum(0);
            slider.setMaximum(360);
            slider.setMinorTickSpacing(5);
            slider.setMajorTickSpacing(10);
            slider.setValue(0);
            add(slider, BorderLayout.SOUTH);
            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    repaint();
                }
            });
        }

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

        public double getAngle() {

            return Math.toRadians(slider.getValue());

        }

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

            Graphics2D g2d = (Graphics2D) g.create();

            g2d.setColor(Color.RED);
            g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
            g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);

            g2d.setColor(Color.BLACK);
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;
            AffineTransform at = new AffineTransform();
            at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2));
            at.translate(x, y);
            g2d.setTransform(at);
            g2d.drawImage(image, 0, 0, this);
            g2d.dispose();

        }
    }
}

更新使用一个JLabel

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
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.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestRotateImage {

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

    public TestRotateImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

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

    public class TestPane extends JPanel {

        private JSlider slider;
        private BufferedImage image;
        private JLabel label;

        public TestPane() {
            setLayout(new BorderLayout());

            label = new JLabel();
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);

            try {
                image = ImageIO.read(new File("/path/to/your/image"));
                label.setIcon(new ImageIcon(image));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            add(label);

            slider = new JSlider();
            slider.setMinimum(0);
            slider.setMaximum(360);
            slider.setMinorTickSpacing(5);
            slider.setMajorTickSpacing(10);
            slider.setValue(0);
            add(slider, BorderLayout.SOUTH);
            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    double radians = Math.toRadians(slider.getValue());
                    double sin = Math.abs(Math.sin(radians));
                    double cos = Math.abs(Math.cos(radians));
                    int newWidth = (int)Math.round(image.getWidth() * cos + image.getHeight() * sin);
                    int newHeight = (int)Math.round(image.getWidth() * sin + image.getHeight() * cos);

                    BufferedImage rotate = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
                    Graphics2D g2d = rotate.createGraphics();
                    int x = (newWidth - image.getWidth()) / 2;
                    int y = (newHeight - image.getHeight()) / 2;
                    AffineTransform at = new AffineTransform();
                    at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2));
                    at.translate(x, y);
                    g2d.setTransform(at);
                    g2d.drawImage(image, 0, 0, TestPane.this);
                    g2d.dispose();
                    label.setIcon(new ImageIcon(rotate));
                }
            });
        }

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

        public double getAngle() {

            return Math.toRadians(slider.getValue());

        }
    }
}


Answer 2:

我解决我自己的问题。 这个问题在代码居士:

myPicture.getType()

由于有大量的图像类型的变化,你可以把在该程序中,结果会当你开始绘制到新的BufferedImage是不可预知的。 我通过显式设置的类型,这在我的情况下,需要解决的问题

BufferedImage.TYPE_INT_ARGB

因此,声明全文如下:

BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);


文章来源: Rotate BufferedImage Inside JPanel