简体   繁体   中英

Java: Rotating image around its center

I am new to Java programming and I am trying to rotate an image using the following code but nothing seems to be working, I searched a lot online but nothing helped. I saw people doing it using BufferedImage but don't want to use that. This code is rotating entire 2d object instead of just image which i want to rotate. I found out this by displaying rectangle as images were not aligned on top of each other. Thanks for your help.


package package3;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Rotate extends JPanel {

    public static void main(String[] args) {
        new Rotate().go();
    }
    
    public void go() {
        JFrame frame = new JFrame("Rotate");
        JButton b = new JButton("click");
        
        MyDrawPanel p = new MyDrawPanel();
        frame.add(p);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000, 1000);
        frame.setVisible(true);
    }
    

    class MyDrawPanel extends JPanel{
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g; 
            Image image = new ImageIcon(
                             getClass()
                            .getResource("wheel.png"))
                            .getImage();
            g2d.drawImage(image, 0, 0, 500, 500, this);
            
            int x = image.getHeight(this);
            int y = image.getWidth(this);
            g2d.rotate(1, x/2, y/2);
            g2d.setBackground(Color.black);
            g2d.drawImage(image, 0, 0, 500, 500, this); 
            g2d.setColor(Color.BLACK);
            g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
        }
    }
}

here's what output looks like

First of all, when rotating an image with a Graphics context, the rotation will occur at a "anchor" point (the top/left is default position if I recall).

So, in order to rotate an image around it's center, you need to set the anchor point to the center of the image WITHIN the context of it's container.

This would mean that the rotate call should be something like...

g2d.rotate(radians, xOffset + (image.getWidth() / 2), yOffset + (image.getHeight() / 2));

Then when you draw the image at xOffset / yOffset , the image will "appear" rotated around the anchor point (or the center of the image).

Second, transformations are compounding. That is, when you transform a graphics context, all subsequent paint operations will be transformed. If you then transform it again, the new transformation will be add to the old one (so if you rotated by 45 degrees and then rotate again by 45 degrees, the transformation would now be 90 degrees).

It's typically "easiest" to create a "copy" of the Graphics state first, apply your transformations and paint operations and then dispose of the copy, which will leave the original context in it's original (transformed) state (all painting operations applied), this way you don't to spend time trying to figure out how to undo the mess

在此处输入图像描述

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
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;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();

                    frame.add(new MyDrawPanel());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    class MyDrawPanel extends JPanel {

        private BufferedImage image;

        public MyDrawPanel() throws IOException {
            image = ImageIO.read(getClass().getResource("/images/MegaTokyo.png"));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1000, 1000);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            drawImageTopLeft(g2d);
            drawImageBottomRight(g2d);
            drawImageMiddle(g2d);

            g2d.rotate(Math.toRadians(45), getWidth() / 2, getHeight() / 2);
            g2d.setColor(Color.BLACK);
            g2d.drawRect(0, 0, this.getWidth(), this.getHeight());
            g2d.dispose();
        }

        protected void drawImageTopLeft(Graphics2D g2d) {
            g2d = (Graphics2D) g2d.create();
            int x = 0;
            int y = 0;

            g2d.rotate(Math.toRadians(135), image.getWidth() / 2, image.getHeight() / 2);
            g2d.drawImage(image, x, y, this);
            g2d.dispose();
        }

        protected void drawImageBottomRight(Graphics2D g2d) {
            g2d = (Graphics2D) g2d.create();
            int x = (getWidth() - image.getWidth());
            int y = (getHeight() - image.getHeight());

            g2d.rotate(Math.toRadians(-45), getWidth() - (image.getWidth() / 2), getHeight() - (image.getHeight() / 2));
            g2d.drawImage(image, x, y, this);
            g2d.dispose();
        }

        protected void drawImageMiddle(Graphics2D g2d) {
            g2d = (Graphics2D) g2d.create();
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;

            g2d.rotate(Math.toRadians(45), getWidth() / 2, getHeight() / 2);
            g2d.drawImage(image, x, y, this);
            g2d.dispose();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM