-1

I'm trying to create an application that lets users modify pictures and then save them. I'm having trouble with the saving part.

This is the method that rotates the picture:

public void process(ImageView imageView) {
    if(imageView.getImage() != null){
        BufferedImage img;
        img = Home.img;
        double rads = Math.toRadians(90);
        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 = w / 2;
        int y = h / 2;

        at.rotate(rads, x, y);
        g2d.setTransform(at);
        g2d.drawImage(img, 0, 0,null);
        g2d.dispose();
        imageView.setImage(convertToFxImage(rotated));
        Home.img = rotated;
    }
}

It sets the image in the Home controller class's imageView and also sets a static field to the modified image. Then I try to save it inside the Home class:

savAs.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            File dir = fileChooser.showSaveDialog(opButton.getScene().getWindow());
            if (dir != null) {
                try {
                    ImageIO.write(img, dir.getAbsolutePath().substring(dir.getAbsolutePath().length() - 3), dir);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });

This for some reason doesn't work. No IOException is thrown, but it doesn't create any file. When I try to save without modifying the image it works. Any idea why?

Bence
  • 109
  • 2
  • 11
  • 1
    You don't need swing to rotate an image. [ImageView javadoc](https://openjfx.io/javadoc/17/javafx.graphics/javafx/scene/image/ImageView.html) provides an example of rotating an image. [Rotate the ImageView](https://openjfx.io/javadoc/17/javafx.graphics/javafx/scene/Node.html#setRotate(double)) which holds the image. – jewelsea May 06 '22 at 20:32
  • 1
    When you want to save it, [snapshot it](https://openjfx.io/javadoc/17/javafx.graphics/javafx/scene/Node.html#snapshot(javafx.scene.SnapshotParameters,javafx.scene.image.WritableImage)), [convert to a BufferedImage](https://openjfx.io/javadoc/17/javafx.swing/javafx/embed/swing/SwingFXUtils.html#fromFXImage(javafx.scene.image.Image,java.awt.image.BufferedImage)), then [write it to a file](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/imageio/ImageIO.html#write(java.awt.image.RenderedImage,java.lang.String,java.io.File)). – jewelsea May 06 '22 at 20:33
  • 1
    If you still have issues, update your question with a complete, executable (by copy and paste) [mcve]. – jewelsea May 06 '22 at 20:34

1 Answers1

1

The method in ImageIO you call is specified below and it returns a boolean status code that you ignore:

public static boolean write(RenderedImage im,
                            String formatName,
                            File output) throws IOException

You haven't included details of the File so there is no way of telling if you have passed in a valid formatName which you derive from the last three characters of the output filename. Note that formatName isn't always 3 characters and should be lowercase - so both "FILE.JPG" and "FILE.JPEG" may fail to save.

If you believe the file extension is correct and is supported by the BufferedImage.TYPE_INT_ARGB format you've used, try change to use lowercase format, then check the result:

String format = dir.getAbsolutePath().substring(dir.getAbsolutePath().length() - 3).toLowerCase();
boolean ok = ImageIO.write(img, format, dir);
if (!ok)
    throw new RuntimeException("Failed to write "+format+" to " + dir.getAbsolutePath());

If the BufferedImage format isn't compatible with the file extension, try using new BufferedImage(... , BufferedImage.TYPE_INT_RGB) or a different format type (eg PNG).

DuncG
  • 12,137
  • 2
  • 21
  • 33