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());
}
}