使用ImageIO保存javafx WritableImage不起作用

时间:2019-05-19 06:46:14

标签: java javafx canvas snapshot javax.imageio

我正在创建一个能够为图像创建遮罩的工具(用于神经网络学习的数据集准备)。假定用户将光标绘制在画布上,该画布嵌套在锚定窗格中,该锚定窗格具有图像作为背景。画布的不透明度设置为0.5。

这是一个基于Intellij Idea的Maven构建的项目。

我认为值得一提的是,Canvas对象不存储有关图像的信息,它设置为黑色,并且通过绘制,用户在其上创建了白色圆圈。

我一直坚持将图像保存到文件中。我已经阅读了很多关于SO的问题,但没有一个对我有用。

我的应用中的屏幕截图: Screenshot of my app

书面图片(应该是带有白色V字样的黑色背景):

Screenshot of rendered image

这是按钮的onClick侦听器的代码(保存文件)。我已将快照的颜色设置为透明,并将图像去饱和度为灰度。

@FXML
    public void onClickButton(ActionEvent evt) throws IOException {

        SnapshotParameters sp = new SnapshotParameters();
        sp.setFill(Color.TRANSPARENT);

        WritableImage image = user_mask_canvas.snapshot(sp, null);

        //desaturafion to get grayscale image
        ImageView desaturated = new ImageView(image);
        ColorAdjust desaturate = new ColorAdjust();
        desaturate.setSaturation(-1);
        desaturated.setEffect(desaturate);

        BufferedImage i =SwingFXUtils.fromFXImage(desaturated.getImage(), null);


        File file = new File("image.bmp");
        if(!file.exists()){
            file.createNewFile();
        }
        System.out.println(file.getAbsolutePath());
        try {
            ImageIO.write(i, "bmp", file);
            System.out.println("written");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

这是完整的代码。

主要:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }


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

控制器:

package sample;

import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    private Button button;

    @FXML
    private AnchorPane image_placeholder;

    @FXML
    private Canvas user_mask_canvas;
    //this is supposed to be in the anchor pane

    private String imgRef;

    final WritableImage wb = new WritableImage(96,96);


    @FXML
    public void onClickButton(ActionEvent evt) throws IOException {

        SnapshotParameters sp = new SnapshotParameters();
        sp.setFill(Color.TRANSPARENT);

        WritableImage image = user_mask_canvas.snapshot(sp, null);

        //desaturafion to get grayscale image
        ImageView desaturated = new ImageView(image);
        ColorAdjust desaturate = new ColorAdjust();
        desaturate.setSaturation(-1);
        desaturated.setEffect(desaturate);

        BufferedImage i =SwingFXUtils.fromFXImage(desaturated.getImage(), null);


        File file = new File("image.bmp");
        if(!file.exists()){
            file.createNewFile();
        }
        System.out.println(file.getAbsolutePath());
        try {
            ImageIO.write(i, "bmp", file);
            System.out.println("written");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void initialize(URL location, ResourceBundle resources) {

        WritableImage image = new WritableImage(96,96);
        try {
            SwingFXUtils.toFXImage(ImageIO.read(getClass().getResource("/1.tif")), image);
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
        BackgroundImage myBI= new BackgroundImage(image,
                BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
                BackgroundSize.DEFAULT);
        image_placeholder.setBackground(new Background(myBI));

        final GraphicsContext graphicsContext = user_mask_canvas.getGraphicsContext2D();
        graphicsContext.setFill(Color.BLACK);
        graphicsContext.fillRect(0, 0, user_mask_canvas.getWidth(), user_mask_canvas.getHeight());
        graphicsContext.setFill(Color.WHITE);
        graphicsContext.setStroke(Color.WHITE);

        user_mask_canvas.addEventHandler(MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent event) {
                        //graphicsContext.beginPath();
                        graphicsContext.moveTo(event.getX(), event.getY());
                        graphicsContext.stroke();

                    }
                });

        user_mask_canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED,
                new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent event) {
                        graphicsContext.lineTo(event.getX(), event.getY());
                        graphicsContext.stroke();
                        graphicsContext.fillOval(event.getX(), event.getY(), 8, 8);
                        //graphicsContext.closePath();
                        //graphicsContext.beginPath();
                        graphicsContext.moveTo(event.getX(), event.getY());
                    }
                });

        user_mask_canvas.addEventHandler(MouseEvent.MOUSE_RELEASED,
                new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent event) {
                        graphicsContext.lineTo(event.getX(), event.getY());
                        graphicsContext.stroke();
                        //graphicsContext.closePath();
                    }
                });
    }
}

sample.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
    <center>
        <HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
            <children>
                <Canvas height="200.0" width="200.0" />
                <AnchorPane fx:id="image_placeholder" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="96.0" prefWidth="96.0">
               <children>
                        <Canvas fx:id="user_mask_canvas" height="96.0" opacity="0.5" width="96.0" />
               </children>
                </AnchorPane>
            <Button fx:id="button" mnemonicParsing="false" onAction="#onClickButton" text="Button" />
            </children>
        </HBox>
    </center>
</BorderPane>

0 个答案:

没有答案