java घुमाए गए बफ़ेदार इमेज जेनरेटर के अंदर




swing rotation (2)

वहाँ जाने के लिए बहुत कुछ नहीं है, लेकिन दो बातें मन में आती हैं। यह संभव है कि छवि को सही स्थिति में रोटेट करने के बाद दो बार रेंडर नहीं किया गया है, जब आप इसे पूरा करते हैं तो आप 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());

        }
    }
}

मैं एक JLabel को घुमाने की कोशिश कर रहा हूं और इसे JLabel अंदर प्रदर्शित कर रहा JLabel (जो कि JLabel अंदर है)। वर्तमान परिणाम एक सफेद वर्ग का काली पृष्ठभूमि के खिलाफ 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));

मैंने अपना मुद्दा हल किया समस्या कोड में रखती है:

myPicture.getType()

चूंकि आप इस कार्यक्रम में शामिल छवियों के प्रकार में बहुत अधिक परिवर्तनशीलता रखते हैं, इसलिए जब आप नए बफर्ड इमेज में ड्राइंग शुरू करते हैं तो परिणाम अप्रत्याशित होने जा रहे हैं। मैंने इस समस्या को स्पष्ट रूप से सेट करके समस्या का हल किया, जो मेरे मामले में आवश्यक था

BufferedImage.TYPE_INT_ARGB

इसलिए पूर्ण बयान पढ़ा:

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




bufferedimage