Entrada no corta …
Como siempre, en el trabajo me pidieron hacer algo que no tenía ni idea de cómo hacer lo que tenía que hacer.
En resumen, vamos a leer huellas dactilares (en el tuto usando el u.are.u 4000B de digitalPersona) desde Java. El modelo del lector, pues, porque ese me pasaron aquí …
Entonces, empezamos por instalar el SDK. Asumo que, si tienen un lector, tienen el SDK. Si no tienen un lector, pues, lean a modo de conocimiento general …
TODO el post se basa en lo leído en la gran serie de Jair Rios en su blog. De modo que, si algo no lo entienden y yo no puedo contestarlo, diríjanse a él
Nos vamos con una app de escritorio. Si quisiéramos hacerlo web, necesitaríamos un applet (que básicamente es lo mismo
).
Personalmente, utilizo IntelliJ como IDE, y le agregué el plugin de jFormBuilder para la interfaz gráfica. En su caso, pueden hacerlo como quieran/puedan.
Y los imports
import com.digitalpersona.onetouch.*; import com.digitalpersona.onetouch.capture.DPFPCapture; import com.digitalpersona.onetouch.capture.event.*; import com.digitalpersona.onetouch.processing.DPFPEnrollment; import com.digitalpersona.onetouch.processing.DPFPFeatureExtraction; import com.digitalpersona.onetouch.processing.DPFPImageQualityException; import com.digitalpersona.onetouch.verification.DPFPVerification; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.GroupLayout; import javax.swing.border.*;
Ahora si. Primero vamos a las variables globales (estamos en una clase que herede de un jPanel o jFrame).
<br />//Nos sirve para identificar al dispositivo<br />private DPFPCapture Lector = DPFPGlobal.getCaptureFactory().createCapture();<br />//Nos sirve para leer a modo de enrrolar, y crear una plantilla nueva, a base de 4 huellas.<br />private DPFPEnrollment Reclutador = DPFPGlobal.getEnrollmentFactory().createEnrollment();<br />//Nos sirve para leer a modo de verificar o comparar, a base de una plantilla creada anteriormente<br />private DPFPVerification Verificador = DPFPGlobal.getVerificationFactory().createVerification();<br />//La plantilla, nueva o rescatada<br />private DPFPTemplate template;<br />//A modo de CONSTANTE para crear plantillas<br />public String TEMPLATE_PROPERTY = "template";<br />//Para leer la huella, y definirla como un enrrolamiento<br />public DPFPFeatureSet featureSetInscripcion;<br />//Para leer la huella, y definirla como una verificación<br />public DPFPFeatureSet featureSetVerificacion;<br />
Siguiente, el constructor
<br />public Enrrolar() {
try{
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,
"No es posible cambiar tema visual",
"LookAndFeel inválido",
JOptionPane.ERROR_MESSAGE);
}
initComponents();
Iniciar();
start();
EstadoHuellas();
btnGuardar.setEnabled(false);
btnIdentificar.setEnabled(false);
btnVerificar.setEnabled(false);
btnSalir.grabFocus();
txtMensaje.setEditable(false);
}
- Cambiar el estilo (es opcional, pero hace que sea vea cool 8) )
- Carga de los elementos. Esta función la genera el IDE.
- Iniciamos todos sus parámetros y eventos del lector.
- Iniciamos el lector.
- Abajo.
- Ordenamos que todos los botones, salvo el de salida, queden desactivados.
Entonces, ahora vamos con Iniciar. El lector tiene sus propios eventos, los cuales linkeamos desde esta función. Nosotros vamos a usar 4:
- dataAcquired, desde Lector.addDataListener
- readerConnected, desde Lector.addReaderStatusListener
- readerDisconnected, desde Lector.addReaderStatusListener también
- errorReader, desde Lector.addErrorListener
Dice:
protected void Iniciar(){
Lector.addDataListener(new DPFPDataAdapter(){
@Override public void dataAcquired(final DPFPDataEvent e){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
EnviarTexto("La huella ha sido capturada");
ProcesarCaptura(e.getSample());}
});
}
});
Lector.addReaderStatusListener(new DPFPReaderStatusAdapter(){
@Override public void readerConnected(final DPFPReaderStatusEvent e){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
EnviarTexto("El sensor de huella dactilar se encuentra Activado");
}
});
}
@Override public void readerDisconnected(final DPFPReaderStatusEvent e){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
EnviarTexto("El sensor de huella dactilar se encuentra Desactivado");
}
});
}
});
Lector.addErrorListener(new DPFPErrorAdapter(){
public void errorReader(final DPFPErrorEvent e){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
EnviarTexto("Error: " + e.getError());
}
});
}
});
}
En todos ocupamos EnviarTexto, pero en el primero al leer la huella, llamamos a otra función.
Vamos a comenzar con EnviarTexto. Únicamente tiene
public void EnviarTexto(String mensaje){
txtMensaje.append(mensaje + "\n");
}
Y txtMensaje es el JTextArea en la parte inferior de la ventana.
Ahora vamos con start (y de paso stop), después EstadoHuellas y luego saltamos a ProcesarCaptura.
public void start(){
Lector.startCapture();
EnviarTexto("Utilizando lector de huella dactilar");
}
public void stop(){
Lector.stopCapture();
EnviarTexto("Lector detenido");
}
Iniciamos y terminamos la captura del lector y, además, mostramos un mensaje por cada evento.
Seguimos con EstadoHuellas
public void EstadoHuellas(){
EnviarTexto("Muestra de huellas necesarias para guardar plantilla: " + Reclutador.getFeaturesNeeded());
}
Únicamente muestra un mensaje con la cantidad de huellas que faltan para completar la plantilla, que por defecto son 4.
Vamos con ProcesarCaptura.
public void ProcesarCaptura(DPFPSample muestra){
featureSetInscripcion = extraerCaracteristicas(muestra, DPFPDataPurpose.DATA_PURPOSE_ENROLLMENT);
featureSetVerificacion = extraerCaracteristicas(muestra, DPFPDataPurpose.DATA_PURPOSE_VERIFICATION);
if(featureSetInscripcion != null){
try {
System.out.println("Las características de la huella han sido creadas");
Reclutador.addFeatures(featureSetInscripcion);
DibujarHuella(CrearImagenHuella(muestra));
btnVerificar.setEnabled(true);
btnIdentificar.setEnabled(true);
} catch (DPFPImageQualityException e) {
System.err.println("Error: "+e.getMessage());
}finally {
EstadoHuellas();
switch (Reclutador.getTemplateStatus()){
case TEMPLATE_STATUS_READY:
stop();
setTemplate(Reclutador.getTemplate());
EnviarTexto("La plantilla de huella ha sido creada. Puede Verificar o Identificarla");
btnIdentificar.setEnabled(false);
btnVerificar.setEnabled(false);
btnGuardar.setEnabled(true);
btnGuardar.grabFocus();
break;
case TEMPLATE_STATUS_FAILED:
Reclutador.clear();
stop();
EstadoHuellas();
setTemplate(null);
JOptionPane.showMessageDialog(Enrrolar.this,
"La plantilla de la huella no pudo ser creada. Repita el proceso",
"Inscripción de Huellas Dactilares",
JOptionPane.ERROR_MESSAGE);
start();
break;
}
}
}
}
Las 2 primeras líneas son para guardar las plantillas que, acabamos de leer o rescatar. Cada una donde corresponde. Las identificamos con el enum DATA_PURPOSE_ENROLLMENT o DATA_PURPOSE_VERIFICATION.
Las 2 las obtenemos llamando a la función extraerCaracteristicas, que tiene lo siguiente:
public DPFPFeatureSet extraerCaracteristicas(DPFPSample muestra, DPFPDataPurpose motivo){
DPFPFeatureExtraction extractor = DPFPGlobal.getFeatureExtractionFactory().createFeatureExtraction();
try{
return extractor.createFeatureSet(muestra, motivo);
} catch (DPFPImageQualityException e) {
System.out.println(e.getMessage());
return null;
}
}
Recibimos el la plantilla con las 4 huellas y si es para guardar o leer. Nada más que eso.
Siguiendo con ProcesarCaptura, en el if, se puede dar el caso que la huella no quede bien leída u ocupemos otro dedo. En esos caso, no cae en la condición porque sería un null.
Al contrario, si todo sale ok, agregamos la huella a la plantilla, y además mostramos la huella en el jLabel que creamos. En realidad, le agregamos un ícono. Dicho paso lo creamos con estas 2 funciones:
public Image CrearImagenHuella(DPFPSample muestra){
return DPFPGlobal.getSampleConversionFactory().createImage(muestra);
}
public void DibujarHuella(Image image){
lblHuella.setIcon(
new ImageIcon(
image.getScaledInstance(
lblHuella.getWidth(),
lblHuella.getHeight(),
Image.SCALE_DEFAULT
)
)
);
}
Simplemente tomamos la huella, la “transformamos” en imagen y la agregamos en el label. Debo decir que hacer esto es muuuucho más simple en Java que en C# (primero aprendí a trabajar con huellas en C#)
Luego habilitamos los botones.
Si pos A, B, o C motivo algo pasa, entramos al catch y simplemente levantamos el error.
Siguiendo con la lógica del sistema, Imprimimos el estado (cuantos nos faltan de los 4). Y luego entramos a un switch y vemos si completamos las 4 lecturas o si algo malo ocurrió.
De estar terminado el proceso (4 lecturas), detenemos el lector y actualizamos la plantilla con las nuevas huellas leídas.
public void setTemplate(DPFPTemplate template) {
DPFPTemplate antigua = this.template;
this.template = template;
firePropertyChange(TEMPLATE_PROPERTY, antigua, template);
}
Luego habilitamos los botónes.
En caso de error, detenemos el lector, limpiamos las huellas que teníamos, vaciamos la plantilla, informamos del error, y luego reiniciamos la lectura.
En el caso de que aún falten huellas, no se hace nada y simplemente seguimos marcando con el dedo.
Y eso es todo
Una vez que aprenda a guardar la info en una BD, agrego el post correspondiente.


















