lunes, 2 de agosto de 2010

Cantidad de Visitas al Articulo:

JTwain - Utilizando el scanner desde Java – Parte 2

Hace varios meses escribí un artículo acerca de la utilización del estándar TWAIN, que resultó ser el mas visitado por lejos. Evidentemente un tema que fue útil.

Desde ya hace algunos días, he recibido varias peticiones a mi mail para que enviara las librerías de mmscomputing, debido a que su sitio no estaba mas en el aire. Es por eso que decidí dejarlas en un sitio compartido para cualquiera que las necesite.

Pueden descargar las librerías aquí.

Cualquier consulta por favor, hacerla a través de los comentarios de este o al anterior artículo.

So far, So good!

Imágenes by TinyPic

Cantidad de Visitas al Articulo:

36 comentarios:

Anónimo dijo...

Hola gustavo, esto es precisamente lo q estaba buscando muchas gracias!...ya me baje ese jar que subiste a esa pagina, pero no se como obtener los jar q se necesitan para crear mi aplicacion... abri el .jar y me sale una aplicacion para instalar y demas.. y luego voy a lo q se extrajo pero no encuentro los 3 .jar q mencionas en el articulo anterior, si me pudieras explicar como utilizar esos archivos t lo agradeceria enormemente. saludos
Alfonso

javdroid dijo...

Hola Gustavo,

Para omitir las páginas en blanco, ¿se utiliza CAP_CLEARPAGE?, si es así ¿cuál es la constante para establecer el valor a true?

Saludos

Gustavo Suhit dijo...

Perdon por estos comentarios, no los habia visto. No se por que no me llegaron al mail.

Alfonso: Que jars necesitas. Me avisas.

Javdroid: No lo se, pero en la clase TwainConstants están todas las constantes y allí puedes verificarlo. Luego en la especificación del estándard segurametne te dará la explicación de cada una.

Sandra: Para escanear en DualMode, tienes que setear la variable CP_DUPLEXEMABLED con true (o 1, según te permita)
en
private void negotiate(ScannerIOMetadata metadata) {
de una forma parecida a esta:

source.setCapability(TwainConstants.CP_DUPLEXEMABLED,1);

o


source.setCapability(TwainConstants.CP_DUPLEXEMABLED,true);

según como esté implementada en la librería de tu escaner.

Saludos a todos,Gustavo.

javdroid dijo...

Hola Gustavo,

vaya ahora he sido yo el que no había visto el mensaje, gracias por responder. Yo también estuve buscando en su momento lo del escaneado a doble cara y lo hice con la constante duplex, pero no he conseguido saber cual es la constante para omitir las páginas en blanco, de momento lo estoy remediando seteándolo en la aplicación de canon, pero es una chapuza, lo quiero hacer desde la aplicación. Luego he visto que otras capabilities no tienen nombres legibles, sino son hexadecimales, ¿eso también funciona?

Por otro lado quiero convertir todas las imágenes escaneadas en pdf (con itext) y una vez hecho borrarlas, ¿cuál es el procedimiento? Yo el que conozco es coger una imagen ya creada y convertirla en pdf, pero me pregunto si hay que hacerlo así, o se podría guardar en memoria y de ahí pasarlo al pdf, ¿se puede hacer eso?

import com.itextpdf.text.Image;
...
try
{
Image img = Image.getInstance("imagen.jpg");
img.scaleToFit(100, 100);
img.setAlignment(Chunk.ALIGN_MIDDLE);
documento.add(img);
}
catch ( Exception e )
{
e.printStackTrace();
}


Saludos

Gustavo Suhit dijo...

javdroid: la variable de la hoja en blanco se que existe, no la recuerdo. Me fijo si la encuentro pero está definida. Ojo que despues está el tema de como implementó cada proveedor de scanner el "estándard" twain de su escáner, que no siempre es "del todo correcto".
Con respecto al PDF, yo siempre lo trabaje como dices tu. Al disco temporal, y cuando armaba el PDF o TIFF (por el tema escaneos multipágina) borraba los temporales. Quizá haya una opción de memoria, pero es riesgoso y dependiendo de la cantidad de info escaneada. De todas formas, la que tu indicas es buena, y funciona bien. Aunque si es cierto que neceita permisos que se deben dar en el java.security, que a los puristas de suguridad no les agradaría mucho :-)
Saludos,

javdroid dijo...

Gracias Gustavo,

La verdad que me haría un favor, es lo único que me queda por hacer, había probado CLEAR_PAGE o algo así pero no estoy seguro de que esa constante sea para omitir las páginas en blanco, la probé pero no funcionó.

Saludos.

jefferson dijo...

Hola Gustavo, ensayé la librería y me funcionó a la perfección.
Por cosas de desarrollo necesité que el llamado al device del Escaner solo se realice una ves, ya que tal como está la librería, si configuras para que no salga el GUI del driver, siempre que haces un llamado al Escaner monta el driver y cuando termina lo desmonta, lo cual lo hace un proceso que toma de 8 a 10 segundos de demora, en ocasiones hasta 15 segundos, cada que haces un llamado para escanear un documento, que es muy demorado para mi caso. Realicé algunos cambios a la clase jtwain de la librería y logre que el proceso fuera más rápido después del primer scan,de dos a 4 segundos,permitiendo que mi aplicación solo cargara la información de escaner la primera vez y fuera mas rápido el proceso por si alguien quiere saber como lo logre(jamora@gmail.com).
saludos desde Cali Colombia.

javdroid dijo...

Hola,

A ver si me podéis ayudar.
Antes me mostraba las capabilities, pero ahora no se que ocurre que escanea pero no me muestra las capabilities, solo esto:

INITIALIZE
OPEN
READY
CANCELLED
CLOSED
EXIT

y el código es este:

try{

// Habilito esto si deseo saber que esta implementado del standard para este scanner
TwainCapability[] cap = source.getCapabilities();
for (int h = 0; h < cap.length; h++) {
System.out.println(cap[h]);
}

String info = source.getInfo();
System.out.println("Informacion: "+(info));

String fabricante = source.getManufacturer();
System.out.println("Fabricante: "+(fabricante));

int identidad = source.getCountry();
System.out.println("Pais: "+(identidad));

String nombre = source.getProductName();
System.out.println("Nombre de Producto: "+(nombre));

int id = source.getId();
System.out.println("Id: "+(id));

String familia = source.getProductFamily();
System.out.println("Familia: "+(familia));

int idioma = source.getLanguage();
System.out.println("Idioma: "+(idioma));

int mn = source.getMajorNum();
System.out.println("MajorNum: "+(mn));

int min = source.getMinorNum();
System.out.println("MinorNum: "+(min));

int pma = source.getProtocolMajor();
System.out.println("ProtocolMajor: "+(pma));

int pmin = source.getProtocolMinor();
System.out.println("ProtocolMinor: "+(pmin));

int sug = source.getSupportedGroups();
System.out.println("SupportedGroups: "+(sug));

TwainITransferFactory tf = source.getTransferFactory();
System.out.println("Transfer Factory: "+(tf));

int estado = source.getState();
System.out.println("Estado: "+(estado));

int mech = source.getXferMech();
System.out.println("XferMech: "+(mech));


//Seteo las unidades a centimetros
source.setCapability(TwainConstants.ICAP_UNITS, TwainConstants.TWUN_CENTIMETERS);
//Seteo el color de la imagen a capturar a escala de grises
source.setCapability(TwainConstants.ICAP_PIXELTYPE, TwainConstants.TWPT_GRAY);
//Seteo la resolucion de la imagen a capturar a 300 Dpi
source.setResolution(300);
//Seteo 'xxxx' para que omita las paginas en blanco

//Seteo escaneado a doble cara
source.setCapability(TwainConstants.CAP_DUPLEXENABLED, true);


} catch (Exception e) {
if (source!=null) source.setCancel(true);
e.printStackTrace();
System.out.println("Source"+e);
}
}


Un saludo
-javier

javdroid dijo...

Es como si el 'source' siguiera a null o algo así.

if (metadata instanceof TwainIOMetadata) {
TwainSource source = null;
try {
source = ((TwainIOMetadata) metadata).getSource();
} catch (Exception ex) {
if (source!=null) source.setCancel(true);
}

javdroid dijo...

Hola Gustavo,

Acerca de crear el PDF, había visto con anterioridad lo de guardar las imágenes como TIFF si se desea hacer multipágina (es mi caso). He probado cambiando el formato y la extensión en el método .write de la clase imageIO, pero me crea un archivo TIFF vacío, 0 Bytes.

ImageIO.write(imagen, "tiff", new File("/home/javdroid/escaneados/"+usuario+("_Documento")+(indice++)+".tiff"));

¿qué puedo estar haciendo mal? ¿debería añadir algo más?.


Un saludo

javdroid dijo...

Hola,

Lo siento ya lo encontré:
Package uk.co.mmscomputing.imageio.

saludos

javdroid dijo...

Hola,

He visto como convertir de Tiff a PDF
http://www.itextpdf.com/examples/iia.php?id=184

http://cfsearching.blogspot.com/2008/01/getting-started-with-itext-part-19.html

pero tengo una duda al pasar la imagen del Buffered a TIFF, ¿lo puedo hacer con import uk.co.mmscomputing.imageio.tiff.TIFFImageWriterSpi; ?

Un saludo

javdroid dijo...

Hola,

para crear el tiff tengo un código así:

BufferedImage imagen=metadata.getImage();
try{
TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_DEFAULT);
param.setCompressionType("LZW");
param.setCompressionQuality(1);


Pero me lanza una excepción al llegar a setCompressionType(), dice:

Source Manager Open
Source Open
Source Enabled
Transfer Ready
Transferring Data
java.lang.IllegalArgumentException: Unknown compression type!
at javax.imageio.ImageWriteParam.setCompressionType(Unknown Source)
at uk.co.mmscomputing.imageio.tiff.TIFFImageWriteParam.setCompressionType(TIFFImageWriteParam.java:54)

Por favor me podrían decir como lo hacen ustedes. ¿les ha funcionado así, añadiendo LZW? porque yo no lo consigo.

Saludos

javdroid dijo...

Sorry, en ComprssionMode es así:

param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

Uchiha Itachi dijo...

Hola Gustavo. mira estoy usando la librería para obtener una imagen del escaner y mostrarla en un formulario. la primera vez todo bien, el problema es si vuelvo a darle en la opción de escanear me tira la siguiente exception:

GRAVE: null
uk.co.mmscomputing.device.twain.TwainIOException: uk.co.mmscomputing.device.twain.TwainSource.checkState:
Source not in state 3 but in state 5.

Pues entiendo lo que quiere decir, o eso creo, pero como hago para que el dispositivo este listo para adquirir la imagen de nuevo?. Te lo agradezco.

shaka dijo...

Hola Uchia Itachi,

Creo que lo puedes hacer con ScannerIOMetadata.STATECHANGE

Yo lo tengo así para cuando termine de adquirir las imágenes las busque en la carpeta guardada y cree el documento PDF, al terminar el pdf, borra todas las imágenes escaneadas.

Revisa si ahí tienes System.exit() porque cierra la aplicación al terminar de adquirir.

Saludos
-javier

-------------------------------------
}else if(type.equals(ScannerIOMetadata.STATECHANGE)){
System.err.println(metadata.getStateStr());
if(metadata.isFinished()){
// Crea un Documento PDF a partir de las imágenes obtenidas
try {
Dirs dirs = new Dirs();
dirs.setDirectorio(dirIMAGES);
fUENTES_JPG = dirs.getListaArchivos();
IMAGE2PDF.setFUENTES_JPG(fUENTES_JPG);
IMAGE2PDF.crearPdf(dirPDF + "documento.pdf");
Dirs.borrarDirectorio(dImages);
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
// System.exit(0);
}

javdroid dijo...

Hola,

¿Alguien me podría decir que clase o archivo carga la librería jtwain.dll?

Estoy teniendo problemas y quería modificar la clase que carga la librería para cambiarle el path, pero hasta ahora no lo he conseguido.

Necesito solucionar esto, agradecería cualquier ayuda.

Un saludo

Ramp dijo...

Hola, he probado y todo funciona perfectamente, gracias por el artículo.
Ahora tengo una serie de preguntas:
1- Como hago para saber si el usuario canceló el escaneo ?
2- Como hago para saber si falló el escaneo ?
3- Probé con una multifuncional y no da excepciones pero tampoco escanea.
4- Con algunos scanners no funcaba si desactivaba la GUI, pq ??
Gracias,

Rudy w dijo...

Hola Gustavo, al parecer a Itachi le ocurrio el mismo error q tengo en este instante y me gustaria saber como le diste solucion, lo que quiero hacer es utilizar el api mas de una vez, mi proceso esta asi, ventana1 es para datos de la imagen, esta llama a ventana2 q es el api mmscomputing al terminar este el escaneo llama a ventana3 para verificar lo escaneado al terminar llama nuevamente a ventana1, el error me aparece cuando hago la llamada a escanear en el api de mmscomputin en la segunda vez que se hace.

Gustavo Suhit dijo...

Gente, ca nuevo link de descarga.
http://www.easy-share.com/1914993850/mmsc.rar

Saludos,

Anónimo dijo...

Me gustaria si alguien me pudiera enviar me la librería mmscomputing (tomo2veo3@hotmail.com), ya que no logro conseguir descargarla de ningun lado. Un saludo y las gracias de antemano.

Anónimo dijo...

hello gustavo i need a code source of mms if you have i would like to do somme change.
and i have question i would like to know how to do configuring the scan source i can choose between flatbed - if the scanner is equipped with one -, ADF single side - simplex scanning, ADF double side - duplex scanning - if supported

laghzaoui.mohammed@yahoo.com

Javi dijo...

Hola Gustavo,

Intento descargarme los fuentes de la librería y no hay forma, dice que ya no existen. ¿Podrías subirlos de nuevo?
Muchísimas gracias.

Javi.

Unknown dijo...

Buenas tardes, estoy desarrollando una aplicacion web con php y mysql, me estan pidiendo que realize una funcion para escanear documentos y vi este articulo y me intereso, no se sobre java y me preguntaba si me podrias orientar sobre esto ya que no se si lo pueda implementar ni como comenzar, un saludo y gracias de antemano.

gastonjp dijo...

Hola gustavo, necesito la libreria pero ya no esta para bajar, me la podrias mandar por mail o resubirla?
Gracias

Miguel dijo...

Hola Gustavo, me ha servido mucho esta librería y me ha funcionado mu bien. Te agradezco el dato. Lo único que no he logrado hacer funcionar es lo siguiente: Necesito levantar la ventana de confuguración de scanner, esa donde seleccionas los dpi, color, escala de grises, etc. Ya que debo colocar un boton y al darle clic levantar esta ventana, he explorado esta librería y no lo he conseguido. Hay alguna forma de hacerlo? tienes algún ejemplo? Muchas gracias por tu ayuda.

Anónimo dijo...

Gustavo gracias por tu ayuda, he estado tratando de escanear una pagina con mi escaner, desarrolle un codigo igual al expuesto en la documentcion de mms-computing pero aun no consigo obtener la imagen y guardarla. Al entrar en la funcion update y validar si el metadata es ACQUIRED no me ingresa por lo tanto no puedo guardar la imagen, solo veo q ingresa a NEGOTIATE y STATECHANGE.
En algun foro lei alguna vez q en algunas ocasiones es nesesario darle permisos a la maquina virtual de java, no se si depronto tenga q hacer eso, quisiera preguntarte si es necesario o si sabes como hacerlo. Gracias

Anónimo dijo...

por favor puedes volver a subir la libreria no la encuentro en la web, el archivo esta eliminado del link, lo necesito urgente para probar en mi proyecto de tesis por favor..

darthmanuel dijo...

Hola como va a todos, leí en unos de los comentarios que pudieron bajar el tiempo de escaneo, me gustaría saber como lo hicieron o si alguien conoce como hacerlo

Jeffeson dijo...

Si claro yo logre disminuir la demora en la escaneada, lo que pasa es que en la librería esta quemado en el código para que se cargue el driver cada vez que mandas a escanear, y la verdad esto solo se debe hacer la primera vez que la utilices, si realizas lo cambio que yo hice solo tendrás demora en el primer Scan pero de ahi en adelante tarda unos 2 segundos. jamora@gmail.com

bcaldera dijo...

Hola Gustavo!
Me parece excelente la opción que proporcionas del manejo de mmscomputing , pero al igual que otros, no he podido descargar las librerías ni desde el sitio oficial, ni desde los otros links que has publicado.

Agradecería mucho que me dieran acceso a ellos, o si es que me los pudieran enviar a mi correo.

Gracias de antemano!

Atentamente,
bcaldera

bcaldera dijo...
Este comentario ha sido eliminado por el autor.
Anónimo dijo...

Muy bueno el post, puedes ayudarme gustavo no tengo ningún link activo para poder bajar el mmsc.jar y si pudieras brindarme algunos ejemplos

sergio dijo...

Hola, quisiera que por favor me brindaras ayuda, es para un aplicación java con scanner el problema radica en que todos los ejemplos del mms-computing estan en JAPPLET y yo trabajo con JAVA 7, tengo problemas para escaner la imagenen ya que en mi caso el metodo UPDATE no se autoejecuta solo sino q ue yo lo tengo que llamar y enviarle los parametros.
Ahora no tengo los parametros
para enviarle ya que son :
public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata)

y no se de donde sacar estos parametros ayudame por favor.
gracias de antemano

Leonardo dijo...

oye amigo no me deja descargar la libreria podrias resubirla porfabor

de antemano racia

Anónimo dijo...

Hola.

Podrias subir los jar, ya no se encuentran en el enlace, por favor.

Gracias

 
Este Weblog, InforMateando..., está licenciado bajo Licencia Creative Common - por Gustavo Suhit