0

I have been trying to rotate an image using for loops. My code does work, but this method seems unnecessary, and the image loses pixels as it rotates. Is there an easier way to do this?

//rotates image around center a degrees
public void drawRotatedImage(Graphics g, BufferedImage image, double a, int x, int y, int pixelSize) {
    //origin point for rotation
    int rX = image.getWidth() / 2;
    int rY = image.getHeight() / 2;

    for(int x1 = 0; x1 < image.getWidth(); x1++) {
        for(int y1 = 0; y1 < image.getHeight(); y1++) {
            int c = image.getRGB(x1, y1);
            //rotating point
            int nX = (int) (((x1-rX) * Math.cos(a)) - ((y1-rY) * Math.sin(a)));
            int nY = (int) (((x1-rX) * Math.sin(a)) + ((y1-rY) * Math.cos(a)));
            g.setColor(new Color(c));
            //drawing each pixel
            g.fillRect((nX*pixelSize) + x, (nY*pixelSize) + y, pixelSize, pixelSize);
        }
    }
}
lue
  • 449
  • 5
  • 16
Kil
  • 1
  • 4
  • 1
    Possible duplicate [Rotate a buffered image in Java](https://stackoverflow.com/questions/37758061/rotate-a-buffered-image-in-java/37758533#37758533). This doesn't use pixel manipulation, but instead makes use of `AffineTransform` - the difference between this example and the other answers? It will resize the image to so the content will fit, which seems to be what you are missing/looking for – MadProgrammer Jan 30 '20 at 21:15

2 Answers2

1

I've created a simple example program (adapted from Rotating BufferedImage instances)

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;

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

        frame.add(new JComponent() {

            BufferedImage image = ImageIO.read(new URL(
                    "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/%D0%9D%D0%B5%D1%80%D0%BF%D0%B8%D1%87%D0%B8%D0%B9_%D0%B2%D0%B7%D0%B3%D0%BB%D1%8F%D0%B4.jpg/500px-%D0%9D%D0%B5%D1%80%D0%BF%D0%B8%D1%87%D0%B8%D0%B9_%D0%B2%D0%B7%D0%B3%D0%BB%D1%8F%D0%B4.jpg"));

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

                AffineTransform at = new AffineTransform();
                at.translate(getWidth() / 2, getHeight() / 2); // draw image in center of frame
                // at.scale(0.5, 0.5);
                at.rotate(Math.toRadians(180));
                at.translate(-image.getWidth() / 2, -image.getHeight() / 2); // rotate around the center

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

            }
        });

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 800);
        frame.setVisible(true);
    }
}
JavaMan
  • 1,142
  • 12
  • 22
  • This isn't actually rotating the image (which seems to be the jist of the question), it's rotating the graphics context use to draw the image – MadProgrammer Jan 30 '20 at 21:13
  • Also, rather then "repeating" what has already been said, if the question is actually a duplicate, it should be marked us such – MadProgrammer Jan 30 '20 at 21:15
0

Try using AffineTransform

get a rotated instance

static void rotate(BufferedImage from, BufferedImage to, double rotate)
{
  // rotate around the center
  AffineTransform trans
  = AffineTransform.getRotateInstance(rotate,
      from.getWidth()/2, from.getHeight()/2);
  AffineTransformOp op = new AffineTransformOp(trans,
                AffineTransformOp.TYPE_BILINEAR);
  op.filter(from, to);
}

or drawing it directly

static void rotate(Graphics2d g2d, BufferedImage img, double rotate)
{
  // rotate around the center
  AffineTransform trans
  = AffineTransform.getRotateInstance(rotate,
      from.getWidth()/2, from.getHeight()/2);

  g2d.drawImage(img, trans, null);
}
lue
  • 449
  • 5
  • 16
  • 1
    One thing though - you need to resize the target image so that the rotated source image will fit without clipping the original image – MadProgrammer Jan 30 '20 at 21:17