Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / Base de Datos / Java / PostgreSQL / Guardar y Leer imagenes en PostgresSQL

Guardar y Leer imagenes en PostgresSQL

Autor jc mouse jueves, junio 14, 2012

En este tutorial veremos una forma para registrar archivos JPG en una base de datos PostgreSQL y recuperarlos para utilizarlos en controles Swing. Como vimos en un tutorial anterior a este donde utilizamos una base de datos MySQL, el procedimiento es prácticamente el mismo, claro con pequeñas diferencias.

¿En que consiste guardar y leer imágenes en una base de datos?

Cuando se desea almacenar fisicamente el contenido de una imagen en una base de datos, este debe ser convertido a una cadena de bytes, para esto el campo donde se guardara la imagen debe ser del tipo BOOL en MySQL y para Postgres tenemos el tipo BYTEA, de esta manera podemos almacenar el contenido de un archivo JPG en la base de datos, ahora para recuperar el contenido de esta imagen y utilizarlo en nuestra aplicación, debemos procesar la cadena de bytes y convertirlo nuevamente en una imagen con la cual podamos trabajar.

Sin más, el tutorial.

Necesitamos

  • Java y Netbeans 6.9 o superior
  • Conector JDBC de Postgres. Yo utilizo postgresql-8.3-603.jdbc3.jar, ya existe la versión 9
  • Imágenes JPG para hacer la prueba no muy grandes.
  • pgAdminIII para trabajar con la base de datos
Nivel: Intermedio Avanzado
Tiempo: 20 minutos
COMENCEMOS.
1. Lo primero que necesitamos es una base de datos en Postgres, utilizando pgAdminIII crea una nueva base de datos [nombre: dbDemoImagen]  y añade la siguiente tabla:
CREATE TABLE imagen
(
  id character(6) NOT NULL,
  nombre character(64),
  archivo bytea
)
2. En netbeans, crea un nuevo proyecto y añade las siguientes clases:
Proyecto
--- Main.java
--- imagen.java
--- interfaz.java
--- postgres.java
Bibliotecas
--- Driver JDBC PostgreSQL
Donde Interfaz.java es de tipo JFrame, esta sera nuestra interfaz de usuario. En
2. En la clase JFrame: Interfaz.java, añade los siguientes controles:
Proyecto Netbeans

Proyecto Netbeans

OJO: Los nombres son importantes
3. Necesitamos una clase donde almacenar nuestra imagen para trabajar en netbeans, esta clase se llama imagen.java, y el código es el siguiente:
import java.awt.Image;
/**
 * @web http://www.jc-mouse.net
 * @author Mouse
 * CLASE PARA ALMACENAR LOS DATOS DE LA TABLA IMAGEN
 */
public class imagen {

    private String id,name;
    private Image archivo;

    public Image getArchivo() {
        return archivo;
    }

    public void setArchivo(Image archivo) {
        this.archivo = archivo;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }    

    @Override
    public String toString() {
        return this.id+" : "+this.name;
    }

}
4. Una clase para la interacción entra nuestra aplicación y la base de datos, esta clase se llama postgres.java:
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.DefaultListModel;
/**
 * @web http://www.jc-mouse.net
 * @author Mouse
 * CLASE PARA CONECTARSE A UNA BASE DE DATOS POSTEGRES, INSERTAR Y RECUPERAR IMAGENES JPG
 */
public class postgres {

   //DATOS PARA LA CONEXION
   private String bd = "dbDemoImagen";
   private String user = "postgres";
   private String password = "";
   private String url = "jdbc:postgresql://localhost:5432/dbDemoImagen/"+bd;

   private Connection connection = null;
   private ResultSet resultSet = null;
   private Statement statement = null;

    //Constructor de clase que se conecta a la base de datoS
    public postgres()
    {
      try{
         Class.forName("org.postgresql.Driver");         
         connection = DriverManager.getConnection(url, user , password);
         System.out.println("Conectado a la base de datos [ " + this.bd + "]");
      }catch(Exception e){
         System.err.println(e.getMessage());
      }
    }

    /* metodo que guarda una imagen JPG en la base de datos
 * input: ID : identificador unico para el registro, osea primary key
 * name: nombre de la imagen para reconocerlo mas adelante
 * ruta: direccion absoluta de la imagen JPG
 */
    public boolean guardarfoto(String id, String name, String ruta) {
        FileInputStream fis = null;
        try {
             File file = new File(ruta);
             fis = new FileInputStream(file);
             PreparedStatement pstm = connection.prepareStatement("INSERT into " +
                        " imagen(id, nombre, archivo) " + " VALUES(?,?,?)");
             pstm.setString(1, id);
             pstm.setString(2, name);
             pstm.setBinaryStream(3, fis,(int) file.length());
             pstm.execute();
             pstm.close();
             return true;
        } catch (FileNotFoundException e) {
             System.out.println(e.getMessage());
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        } finally {
            try {
               fis.close();
             } catch (IOException e) {
               System.out.println(e.getMessage());
             }
        }
        return false;
   }

    /* Metodo que convierte una cadena de bytes en una imagen JPG
 * input:
 * bytes: array que contiene los binarios de la imagen
 * Output: la foto JPG en formato IMAGE
 */
 private Image ConvertirImagen(byte[] bytes) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");    
    ImageReader reader = (ImageReader) readers.next();
    Object source = bis;
    ImageInputStream iis = ImageIO.createImageInputStream(source);
    reader.setInput(iis, true);
    ImageReadParam param = reader.getDefaultReadParam();
    return reader.read(0, param);
 }

 /* Metodo que extrae los registros de la tabla IMAGEN de la base de datos
 * crea instancia nueva de la clase imagen.java y añade los datos
 * agrega estos datos a un DefaultListModel
 * output:
 * dml: Es un DefaultListModel que contiene instancia de la clase imagen.java
 */
    public DefaultListModel Lista_Imagenes()
    {
        DefaultListModel dml = new DefaultListModel();
        try {
            statement = connection.createStatement();
            resultSet = statement.executeQuery("SELECT id,nombre,archivo FROM imagen " );
          while (resultSet.next())
          {  //se crea un objeto CITA y se le van agregando los datos
             imagen img = new imagen();
             img.setId( resultSet.getString("id") ) ;
             img.setName( resultSet.getString("nombre") ) ;
             try { //antes de agregar el campo imagen, realiza la conversion de bytes a JPG
                 img.setArchivo(ConvertirImagen(resultSet.getBytes("archivo")));
             } catch (IOException ex) {
                System.err.println(ex.getMessage());
             }
             //por ultimo añade el objeto imagen:img al DefaultListModel
            dml.addElement(img);
          }
       }
       catch (SQLException ex) {
          System.err.println(ex.getMessage());
       }
       return dml;
    }

}
5 Para terminar debemos implementar todo en nuestra interfaz.
los import que utilizamos son:
import java.awt.Image;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
Declaramos también :
private postgres Pg = new postgres();
    //Para almacenar la clase imagen
    private DefaultListModel modListaImagen = new DefaultListModel();
En el constructor de clase declaramos:
 /** Creates new form interfaz */
    public interfaz() {
        initComponents();
        this.setTitle("Postreges Imagenes Save/Open [http://www.jc-mouse.net/]");
        this.setLocationRelativeTo(null);
        //se carga los registros de la base de datos
        Actualizar_lista();
    }
Creamos tambien dos métodos privados:
    //Se conecta a la base de datos y obtiene registros
    private void Actualizar_lista()
    {
        this.modListaImagen.clear();
        this.modListaImagen = Pg.Lista_Imagenes();
        this.Lista_Imagenes.setModel(modListaImagen);
    }

    //Genera un código unico para la imagen
    private String GenerarCodigo()
    {
        SimpleDateFormat sdf= new SimpleDateFormat("hhmmss");
        return sdf.format(new Date());
    }
En el evento Clicked del JLista colocamos:
private void Lista_ImagenesMouseClicked(java.awt.event.MouseEvent evt) {                                    
        int index = this.Lista_Imagenes.getSelectedIndex();//obtiene index seleccionado
        if( index != -1)
        {
            //Extrae la clase imagen que corresponde a la posición donde se hizo un clic
            imagen img = (imagen)this.modListaImagen.getElementAt(index);
            //redimensiona imagen
            double alto = img.getArchivo().getHeight(null) / Math.ceil(img.getArchivo().getHeight(null)/300f) ;
            double ancho =img.getArchivo().getWidth(null) / Math.ceil(img.getArchivo().getWidth(null)/320f) ;
            Icon icon = new ImageIcon( img.getArchivo().getScaledInstance((int)ancho,(int)alto, Image.SCALE_AREA_AVERAGING) );            
            this.FOTO.setText("");
            this.FOTO.setIcon( icon  );//coloca imagen en el JLabel
        }
    }
Para terminar en el evento ActionPerformed del item del menu jmSave, colocamos
 private void jmSaveActionPerformed(java.awt.event.ActionEvent evt) {                                       
       JFileChooser fileChooser = new JFileChooser();
       fileChooser.setFileFilter( new FileNameExtensionFilter("Archivo de Imagen","jpg") );
       fileChooser.setCurrentDirectory(new java.io.File("e:/imagenes_tmp/"));
       int result = fileChooser.showOpenDialog(null);
        if ( result == JFileChooser.APPROVE_OPTION ){
            //obtiene ruta y nombre del archivo
            String ruta = fileChooser.getSelectedFile().getAbsolutePath();
            String name = fileChooser.getSelectedFile().getName();
            if( Pg.guardarfoto( GenerarCodigo() , name, ruta ) )
            {
                JOptionPane.showMessageDialog(this,"Imagen ["+name+"] almacenada en la base de datos");
                Actualizar_lista();
            }
        }
    }
Terminamos y no deberíamos tener ningún problema, si es así, revisa todos los pasos nuevamente, caso contrario ejecuta el proyecto:
pg imagen
  • Descargate el proyecto en Netbeans 6.9 AQUI

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Escritura y lectura de archivos CSV

Escritura y lectura de archivos CSV

Los archivos CSV (del inglés comma-separated values – separados por comas) son un tipo de documento en formato abi...

Código de Control v7 en JavaScript

Código de Control v7 en JavaScript

En esta oportunidad, se deja a disposición de la comunidad de programadores de Bolivia y también porque no, del que quie...

Insert, Update, Delete con Access y C#

Insert, Update, Delete con Access y C#

En un post anterior vimos la forma de conectarnos a una base de datos Access con C#, pero de nada nos sirve solo conecta...

Introducción a Fragment

Introducción a Fragment

Un Fragment representa un comportamiento o una parte de la interfaz de usuario en una Activity. Puedes combinar múltiple...

GraphADT: Clases para trabajar con grafos en java

GraphADT: Clases para trabajar con grafos en java

GraphADT es una proyecto alojado en github escrito en java que te permite trabajar con grafos, a la fecha de escribir es...

Empaquetado de texturas en LibGDX

Empaquetado de texturas en LibGDX

Continuando con los tutoriales sobre LibGDX (Librería para el desarrollo de videojuegos), en esta ocasión veremos como e...

11 comentarios en “Guardar y Leer imagenes en PostgresSQL”

  1. Javier dice:

    Disculpa, pero seguí todos los pasos al pie de la letra y aún así me sale la siguiente excepción:

    Not a JPEG file: starts with 0xe6 0x64
    Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
    at jcimagendb.interfaz.Lista_ImagenesMouseClicked(interfaz.java:147)
    at jcimagendb.interfaz.access$000(interfaz.java:16)
    at jcimagendb.interfaz$2.mouseClicked(interfaz.java:80)

    Podrías ayudarme? Ya realizé el procedimiento 3 veces y me sigue saliendo el mismo error.
    Gracias

    1. Eliana dice:

      Hola, tengo un error al hacerlo con mysql,
      java.lang.NullPointerException….. con respecto a la linea:
      jlist.setModel(modListaImagen);

      A que se debe esto… x favor ayuda.

      1. Mouse dice:

        si quieres utilizar mysql en lugar de postgres este enlace te puede servir
        http://jc-mouse.blogspot.com/2009/12/cargar-imagenes-ej-java-mysql-con.html

        aunque si te fijas los procedimientos son prácticamente los mismos 🙂

  2. jhonzizi dice:

    Bueno Mouse Antes darte las gracias tu pagina es de gran ayuda para todos los novatos y expertos programadores hasta donde yo lo veo, claro que yo me incluyo ya que me ayudo en las peores y aun lo hace jejeje.
    Bueno mi problema es el mismo que Javier la imagen se guarda exelente pero al momento de recuperar me aparese el error y no muestra nada ya probe todo lo que mi escaso conosimieto me permite claro con ayuda de internet pero aun asi nada creo que el problema esta en el metodo de conversion para ser mas exacto en esta linea
    ImageReadParam param = reader.getDefaultReadParam(); nose si le darias una revisadita y aver si me puedes ayudar en esto GRACIAS y SIGUE ADELANTE que sin ti no arimos mucho

    1. Mouse dice:

      :/ ok, revisare el codigo

  3. Gustavo dice:

    Muy buena información… Te felicito…. Muy bueno… lo recomendaría excelente.

  4. Andres dice:

    gran aporte pero por mas que e intentado monstrar la imagen no me deja de ninguna manera quisiera saber si alguno ya pudo solucionar el problema agradeceria su ayuda…

  5. Cinthia dice:

    Muchísimas gracias por la ayuda, muy útil el blog, me ayudo a terminar el Proyecto
    Saludos desde Paraguay

  6. Rodmar dice:

    Saludos. lo necesito para c# en especial el codigo de recuperar la imagen guardada. ayudame porfavor

  7. ORION dice:

    Saludos, estimados si me pueden ayudar pero usando vb6 + postgresql9.4

  8. Elvis Mujica dice:

    Me sirvio Muchisimo el codigo, pero ahora quiero descargar de vuelta el archivo y no se como hacerlo, podrias ayudarme

Los comentarios estan cerrados

Comparte lo que sabes

Categorias

Últimas entradas

En este post aprenderemos lo que es la clonación de objetos en java o lo que es lo mismo, generación de nuevas instancia...

El índice TIOBE (TIOBE, The Importance of Being Earnest – “La importancia de ser honesto” – refe...

SDKMAN! es una herramienta para la administración de versiones paralelas de varios programas de desarrollo de software c...

Continuando con el estudio del meta lenguaje XML (Lenguaje de Marcado Extensible) bastante utilizado en el intercambio d...

Android Bolivia

MAUS