insert image in SQL field IMAGE with Java

0

I want to save my image in a database in SQL in a field called fotoEmpleado of type IMAGE , until then everything is fine, because I am saved in BYTES

The problem is when reading it, I want to show it in a Label on my form, I understand that it is getting that array of BYTES and convert it to an image but it sends me an error java.lang.NullPointerException and I do not know how to read it. I leave my classes and methods that I use (MVC):

Method that makes the query and receives as a parameter the idEmployed:

public static String getImagenEmpleado(int idEmpleado) {

    String consulta = "SELECT fotoEmpleado FROM Empleado WHERE idEmpleado="+idEmpleado;
    return consulta;
}

Method that makes the connection to the DB and executes the query and converts the BYTES to IMAGE :

public Image obtenerImagen(int idEmpleado) throws Exception {
    Image foto = null;
    //Creamos un objeto de conexion:
    ConexionSQL conexion = new ConexionSQL();
    //Declaramos el ResultSet:
    ResultSet rs = null;
    Statement stmt = null;
    //Establecemos la conexion con la BD:
    ConexionSQL.conectar();

    stmt = ConexionSQL.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    rs = stmt.executeQuery(CommandsEmpleado.getImagenEmpleado(idEmpleado));

    //Iteramos sobre cada registro devuelto:
    if (rs.next()) {//si no encuentra la imagen
        Blob blob = rs.getBlob("fotoEmpleado");
        foto = javax.imageio.ImageIO.read(blob.getBinaryStream());
    }

    //Cerramos el ResultSet:
    rs.close();
    stmt.close();

    //Cerramos la conexion:
    conexion.desconectar();

    //Devolvemos la foto del Empleado
    return foto;
}

and in the view I send the parameter idEmployed and I send the image to the label:

ImageIcon image = new ImageIcon(controladorEmpleado.obtenerImagen(idEmpleado));

                if (image.getIconHeight() > 342 || image.getIconWidth() > 230) {
                    ImageIcon imageScalada = new ImageIcon(image.getImage().getScaledInstance(90, 100, 100));
                    lblFotoEmpleado.setIcon(imageScalada);
                } else {
                    lblFotoEmpleado.setIcon(image);
                }
                ;
            } catch (Exception ex) {
                Logger.getLogger(PanelEmpleados.class.getName()).log(Level.SEVERE, null, ex);
        }

or does anyone know another way to save and display the image in SQL and Java?

    
asked by Isidro Martínez 09.08.2017 в 07:10
source

2 answers

1

I think you're never giving value to the variable foto analyzing this snippet of code:

//Iteramos sobre cada registro devuelto:
if (!rs.next()) {//si no encuentra la imagen
    Blob blob = rs.getBlob("fotoEmpleado");
    foto = javax.imageio.ImageIO.read(blob.getBinaryStream());
}

It follows that it only gives value to foto if the courses had reached their last pointer on the ResultSet. This will never happen as long as there are values in the ResultSet. So, you should do the opposite:

// Se valida que existen valores.
if (rs.next()) { <-- // En caso de que existan valores
    Blob blob = rs.getBlob("fotoEmpleado");
    foto = javax.imageio.ImageIO.read(blob.getBinaryStream());
}

I leave a link to the documentation of next () ;

    
answered by 09.08.2017 в 08:55
0

Maybe you should use BufferedImage instead of Image.

BufferedImage foto = javax.imageio.ImageIO.read(blob.getBinaryStream());

Image as such is an abstract class, whereas BufferedImage extends from it and is the one that I have seen that is implemented for this kind of situations.

EDIT: I was doing several tests with parts of your code and I did not get the error of the null, I show you the way I did it to load the image of the database.

 public Image obtenerImagen(int idEmpleado) throws Exception {
    BufferedImage foto = null;
    //Declaramos el ResultSet:
    ResultSet rs = null;
    Statement stmt = null;
    //Establecemos la conexion con la BD:
    stmt = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    rs = stmt.executeQuery("SELECT image FROM imagetest LIMIT 1;");
    //Iteramos sobre cada registro devuelto:
    if (rs.next()) {//si no encuentra la imagen
        Blob blob = rs.getBlob("image");
        foto = ImageIO.read(blob.getBinaryStream());
    }
    //Cerramos el ResultSet:
    rs.close();
    stmt.close();
    //Devolvemos la foto del Empleado
    return foto;
}

As you can see, it is basically your same code, only that I change the Image for BufferedImage and other details to bring the information from my database (like my own connection, the fact that I do not need the id of the employee, etc), but the rest is the same.

Regarding the visualization part, your code served basically the same, just adapt it to work for me.

ImageIcon image = new ImageIcon(imageManager.obtenerImagen(1));
    JLabel lblFotoEmpleado = new JLabel();
    Frame frame = new Frame("Image Example");
    frame.setSize(400,400);
    lblFotoEmpleado.setSize(400,400);
    lblFotoEmpleado.setVisible(true);

    if (image.getIconHeight() > 342 || image.getIconWidth() > 230) {
        ImageIcon imageScalada = new ImageIcon(image.getImage().getScaledInstance(90, 100, 100));
        lblFotoEmpleado.setIcon(imageScalada);
    } else {
        lblFotoEmpleado.setIcon(image);
    }

    frame.add(lblFotoEmpleado);
    frame.setVisible(true);
}

The only thing that occurs to me that we have different, is the way in which the image is saved in the database. I then use a Longblob, which I suppose that you too, and when you save it in the database, shows me the following, in comparison to you that shows the Bytes.

If anything, the code you use to save the images was as follows.

 public void saveImage(String ruta) throws SQLException, FileNotFoundException
{
    String sql = "INSERT INTO imagetest(image) VALUES (?)";
    //Creamos una cadena para después prepararla
    PreparedStatement stmt = connection.prepareStatement(sql);
    File image = new File(ruta);
    //ruta puede ser: "/home/cmop/Desktop/1.jpg"
    FileInputStream fis = new FileInputStream(image);
    //Lo convertimos en un Stream
    stmt.setBinaryStream(1, fis, (int) image.length());
    //Asignamos el Stream al Statement
    stmt.execute();
}

I'm sorry I can not help you anymore, the truth, apart from what I told you, I can not think of another cause of error.

    
answered by 10.08.2017 в 01:03