Lectura de metadatos EXIF de imágenes en Java con mapeo a objetos

Para extraer y organizar la información EXIF almacenada en archvios de imagen JPEG, es posible utilizar bibliotecas especializadas en Java. Este enfoque permite seleccionar los parámetros más relevantes del conjunto total de metadatos y estructurarlso dentro de un objeto de transferencia de datos (DTO).

Configuración de la dependnecia

Se requiere incluir la biblioteca metadata-extractor en el archivo de configuración del proyecto.


<dependency>
    <groupId>com.drewnoakes</groupId>
    <artifactId>metadata-extractor</artifactId>
    <version>2.19.0</version>
</dependency>

Implementación del extractor de metadatos

El siguiente método procesa un archivo de imagen y devuelve un objeto con la información EXIF estructurada.


import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.jpeg.JpegMetadataReader;
import java.io.File;
import java.io.IOException;
import java.util.Optional;

public class ExtraccionExif {

    public static DatosExif obtenerDatosExif(File archivoImagen) throws ImageProcessingException, IOException {
        DatosExif datos = new DatosExif();
        Metadata metadata = JpegMetadataReader.readMetadata(archivoImagen);
        
        metadata.getDirectories().forEach(directorio -> {
            directorio.getTags().forEach(etiqueta -> {
                mapearEtiqueta(datos, etiqueta);
            });
        });
        
        return datos;
    }

    private static void mapearEtiqueta(DatosExif datos, Tag etiqueta) {
        String nombre = etiqueta.getTagName();
        String valor = etiqueta.getDescription();
        
        switch (nombre) {
            case "Make":
                datos.setFabricante(valor);
                break;
            case "Model":
                datos.setModeloCamara(valor);
                break;
            case "Orientation":
                datos.setOrientacion(valor);
                break;
            case "Date/Time":
                datos.setFechaCaptura(valor);
                break;
            case "Exposure Time":
                datos.setTiempoExposicion(valor);
                break;
            case "F-Number":
                datos.setNumeroApertura(valor);
                break;
            case "ISO Speed Ratings":
                datos.setIso(valor);
                break;
            case "Focal Length":
                datos.setDistanciaFocal(valor);
                break;
            case "Exif Image Width":
                datos.setAnchoPixeles(valor);
                break;
            case "Exif Image Height":
                datos.setAltoPixeles(valor);
                break;
            case "Lens Model":
                datos.setModeloLente(valor);
                break;
            case "White Balance Mode":
                datos.setBalanceBlanco(valor);
                break;
            case "Flash":
                datos.setUsoFlash(valor);
                break;
            case "Metering Mode":
                datos.setModoMedicion(valor);
                break;
            case "Color Space":
                datos.setEspacioColor(valor);
                break;
            default:
                break;
        }
    }
}

Clase para almacenar los datos EXIF

La estructura del DTO utiliza nombres de campo en español para reflejar las propiedades seleccionadas.


public class DatosExif {
    private String fabricante;
    private String modeloCamara;
    private String orientacion;
    private String fechaCaptura;
    private String tiempoExposicion;
    private String numeroApertura;
    private String iso;
    private String distanciaFocal;
    private String anchoPixeles;
    private String altoPixeles;
    private String modeloLente;
    private String balanceBlanco;
    private String usoFlash;
    private String modoMedicion;
    private String espacioColor;
    
    // Getters y setters
    public String getFabricante() {
        return fabricante;
    }
    public void setFabricante(String fabricante) {
        this.fabricante = fabricante;
    }
    public String getModeloCamara() {
        return modeloCamara;
    }
    public void setModeloCamara(String modeloCamara) {
        this.modeloCamara = modeloCamara;
    }
    public String getOrientacion() {
        return orientacion;
    }
    public void setOrientacion(String orientacion) {
        this.orientacion = orientacion;
    }
    public String getFechaCaptura() {
        return fechaCaptura;
    }
    public void setFechaCaptura(String fechaCaptura) {
        this.fechaCaptura = fechaCaptura;
    }
    public String getTiempoExposicion() {
        return tiempoExposicion;
    }
    public void setTiempoExposicion(String tiempoExposicion) {
        this.tiempoExposicion = tiempoExposicion;
    }
    public String getNumeroApertura() {
        return numeroApertura;
    }
    public void setNumeroApertura(String numeroApertura) {
        this.numeroApertura = numeroApertura;
    }
    public String getIso() {
        return iso;
    }
    public void setIso(String iso) {
        this.iso = iso;
    }
    public String getDistanciaFocal() {
        return distanciaFocal;
    }
    public void setDistanciaFocal(String distanciaFocal) {
        this.distanciaFocal = distanciaFocal;
    }
    public String getAnchoPixeles() {
        return anchoPixeles;
    }
    public void setAnchoPixeles(String anchoPixeles) {
        this.anchoPixeles = anchoPixeles;
    }
    public String getAltoPixeles() {
        return altoPixeles;
    }
    public void setAltoPixeles(String altoPixeles) {
        this.altoPixeles = altoPixeles;
    }
    public String getModeloLente() {
        return modeloLente;
    }
    public void setModeloLente(String modeloLente) {
        this.modeloLente = modeloLente;
    }
    public String getBalanceBlanco() {
        return balanceBlanco;
    }
    public void setBalanceBlanco(String balanceBlanco) {
        this.balanceBlanco = balanceBlanco;
    }
    public String getUsoFlash() {
        return usoFlash;
    }
    public void setUsoFlash(String usoFlash) {
        this.usoFlash = usoFlash;
    }
    public String getModoMedicion() {
        return modoMedicion;
    }
    public void setModoMedicion(String modoMedicion) {
        this.modoMedicion = modoMedicion;
    }
    public String getEspacioColor() {
        return espacioColor;
    }
    public void setEspacioColor(String espacioColor) {
        this.espacioColor = espacioColor;
    }
}

El método principal demostraría el uso de la funcionalidad.


public static void main(String[] args) {
    try {
        File imagen = new File("ruta/a/la/imagen.jpg");
        DatosExif metadatos = obtenerDatosExif(imagen);
        System.out.println("Fabricante: " + metadatos.getFabricante());
        System.out.println("Modelo: " + metadatos.getModeloCamara());
        System.out.println("Fecha: " + metadatos.getFechaCaptura());
        System.out.println("ISO: " + metadatos.getIso());
    } catch (Exception e) {
        System.err.println("Error procesando la imagen: " + e.getMessage());
    }
}

Etiquetas: java EXIF metadata-extractor procesamiento-imágenes JPEG

Publicado el 7-7 00:24