0

I'm using AffineTransform to rotate the image and I had tried to save the rotated image by ImageIo.write it is saving the image but not the rotated image it's saving the original image. so please tell me how to correct it Thanks in advance.

This is my code for rotation and saving the image

public class Image {

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

public Image() {
    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 static final long serialVersionUID = 1L;
    private JSlider slider;
    private BufferedImage image;

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

        try {
           File imagefile = new File("C:/pics/1206.jpg");
              image = ImageIO.read(imagefile);


              ImageIO.write(image, "jpg",new File("C:/pics"));
              ImageIO.write(image, "bmp",new File("C:/pics"));
              ImageIO.write(image, "gif",new File("C:/picsf"));
              ImageIO.write(image, "png",new File("C:/pics"));
        } 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();
    }
    }
}
  • 1
    Please add the relevant code about the writing part . – Arnaud Jun 28 '17 at 10:04
  • Sorry Berger now i had updated my code u can check – Niti kapoor Jun 28 '17 at 10:13
  • [This example](https://stackoverflow.com/questions/20275424/rotating-image-with-affinetransform/20280225#20280225) will generate a new image when it's rotated, this means you can use `ImageIO.write` to save it – MadProgrammer Jun 28 '17 at 11:01
  • thanks, MadProgrammer but I'm already using the ImageIO.write but its saving a original image not rotated image. – Niti kapoor Jun 28 '17 at 11:06
  • None of your calls to `ImageIO.write()` occur after the image is rotated. All specify a `parent`, none specify a `child`. – trashgod Jun 28 '17 at 11:44
  • @Nitikapoor BUT you're not actually rotating the image, you're just rotating the `Graphics` context of the the component, so the original image won't change - the example I've linked, will create a NEW rotated image (based on the original), which you can then save – MadProgrammer Jun 28 '17 at 20:50
  • thanks a lot i got ur point very clear – Niti kapoor Jun 29 '17 at 04:28

1 Answers1

1

Let's start with, this isn't rotating the image, it's rotating the Graphics context which is used to display the image, it doesn't affect the original image at all

@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();
}

And then this...

  try {
        File imagefile = new File("C:/pics/1206.jpg");
        image = ImageIO.read(imagefile);


        ImageIO.write(image, "jpg",new File("C:/pics"));
        ImageIO.write(image, "bmp",new File("C:/pics"));
        ImageIO.write(image, "gif",new File("C:/picsf"));
        ImageIO.write(image, "png",new File("C:/pics"));
  } catch (IOException ex) {
        ex.printStackTrace();
  }

which just saves the original image to a number of different formats ... to the same file , but doesn't even react to any changes to the angle

Instead, you need to use something which generates a new image from the original, rotated by the amount you want...

  public BufferedImage rotateImageByDegrees(BufferedImage img, double degrees) {
        double rads = Math.toRadians(degrees);
        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 = clickPoint == null ? w / 2 : clickPoint.x;
        int y = clickPoint == null ? h / 2 : clickPoint.y;

        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;
  }

Then you can save it...

File imagefile = new File("C:/pics/1206.jpg");
image = ImageIO.read(imagefile);

BufferedImage rotated = rotateImageByDegrees(image, 22.5);
ImageIO.write(rotated, "png", new File("RotatedBy225.png"));

So, the next time you use one of my previous examples and I tell you it's not doing what you think/want it to, I hope you will understand my meaning better and look more closly at the other examples we show you

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • thank's a ton but in ur example getAngle is giving the error – Niti kapoor Jun 29 '17 at 04:29
  • And u assigned to Clickpoint – Niti kapoor Jun 29 '17 at 04:42
  • Sorry, copy/pasted the code - `getAngle` can be replaced with `degrees`, but I’ve changed it to just use `rads` ... and no – MadProgrammer Jun 29 '17 at 04:54
  • everything is working fine with this thanx but it's not saving the image the exception im getting are Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: image == null! at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(Unknown Source) at javax.imageio.ImageIO.getWriter(Unknown Source) at javax.imageio.ImageIO.write(Unknown Source) at tilti.Image$RotationPane.(Image.java:78) at tilti.Image$1.run(Image.java:39) – Niti kapoor Jun 29 '17 at 05:23
  • You're passing `ImageIO` a `null` reference, you'll need to figure out why – MadProgrammer Jun 29 '17 at 05:39