mysqljavafxjava-20

Save and Retrieve image files in Mysql and Javafx


In My JavaFX application, I want to save and retrieve image files. But I can't get the solutions. I tried so many Solutions. But I can't get a solution. In those solutions I can save the image file and but I can't retrieve and display in ImageView. There is no error showing. But I can't get the solution for this. I don't know where is the mistake. So Please look into my Image saving code and retrieving code and help to solve this issue. Thanks in Advance.

This is my Show Image Code

private void showImage(String id) {
        Image img = null;
        try {
            PreparedStatement pst = db.con.prepareStatement("select image from " + db.schema + ".tbl_user where code = ?");
            pst.setString(1, id);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                Blob image = rs.getBlob("image");
                InputStream imgFile = image.getBinaryStream();
                img = new Image(imgFile) ;
                imgFile.close();
                imgView.setFitHeight(120);
                imgView.setFitWidth(120);
                imgView.isSmooth();
                imgView.setImage(img);
                lblPic.setText("");
            } else {
                lblPic.setText("Photo");
            }
        } catch (Exception e) {
            Alert alt = new Alert(Alert.AlertType.ERROR,e.getMessage(),ButtonType.OK);
            alt.show();
            throw new RuntimeException(e);
        }
    }

This How I select the Image to Save.

 FileChooser chooser = new FileChooser();
 FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG","*.JPEG","*.jpeg");
 FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG");
 chooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG);
 File file = chooser.showOpenDialog(stage_Emp);
   if(file != null){
      Image image = new Image(file.toURI().toString());
      imgView.setFitHeight(120);
      imgView.setFitWidth(120);
      imgView.isSmooth();
      imgView.setImage(image);
      img_path=file.getAbsolutePath();
   }

And This is How I save the Image

 FileInputStream fis = new FileInputStream(img_path);
 PreparedStatement pst = db.con.prepareStatement("UPDATE "+db.schema+".tbl_user SET image=? Where code=?");
 pst.setBinaryStream(1,fis,(int)img_path.length());
 pst.setString(2, txtID.getText());
 pst.executeUpdate();

Solution

  • The problem appears to be in the way you are writing the data to the database.

    Since you are doing (for some unknown reason)

    imgPath = file.getAbsolutePath();
    

    imgPath must be a String (the string representation of the absolute path of the file). Then it makes no sense to do

    pst.setBinaryStream(1,fis,(int)imgPath.length());
    

    The third parameter to that method call is supposed to be the number of bytes in the stream, not the number of characters in the name of the file.

    If you do

    Image image = new Image(file.toURI().toString());
    

    and then

    FileInputStream fis = new FileInputStream(file);
    PreparedStatement pst = db.con.prepareStatement("UPDATE "+db.schema+".tbl_user SET image=? Where code=?");
    pst.setBinaryStream(1,fis,file.length());
    pst.setString(2, txtID.getText());
    pst.executeUpdate();    
    

    (getting the length of the file instead of the length of the filename) it should work. There is no need at all to know the name of the file.

    However, there's no real need to get the length of the file anyway. Just let it read to the end of the file stream. Additionally, since you are using a BLOB field in the database, you could also just do

    pst.setBlob(1, fis);
    

    which can be slightly more efficient than pst.setBinaryStream(...).

    When you load the image, you can check for errors with

    if (img.isError()) {
        img.getException().printStackTrace();
    }
    

    to see the stack trace if an exception is thrown loading the image.