基于Applet的Web在线扫描仪控件

yanhandle 2011-11-19

基于JAVAEE的B/S架构由于java语言的跨平台性

所以操控Window客户端资源能力有限,

目前比较流行是用其他语言如Delphi,VB,C++开发客户端控件

然后再html中用js调用。

但对于java开发者而言,这种方式比较不方便,尤其在分工合作

而对方开发水平也有限的情况下,调试比较繁琐。

统观现在的在线扫描控件,大部分都是收费的,无论国内还是国外。

收费,代码不可见应该是JAVA程序员比较反感的吧,总感觉受制于人,至少我是这样的啊。

Applet现在虽然不流行被ActiveX所替代,但对java程序员开发B/S架构

需要操纵客户端资源,还是比较可行的。

尤其是在HtmlConvert的出现后,其编程方式可以把Applet标签转换成

object标签。

虽说需要客户端下载并安装JRE,下载速度比较慢,但由于是在企业级应用的局域网的

环境下,这些并不是最大的缺点。(现在jre可以通过cab包的形式在客户端自动下载及安装jre,通过改变url让此cab在局域网内下载

html中如下:<object

classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"

codebase="http://localhost:8090/emr-archive-app/arc/cabs/jinstall-1_5-windows-i586.cab#Version=5,0,0,5"

width="240"VSPACE="20"alt="Sorry">

<PARAMNAME=CODEVALUE="com.founder.applet.scan.ScannerApplet.class">

<PARAMNAME=ARCHIVEVALUE="scanner.jar">

<paramname="type"value="application/x-java-applet;version=1.5">

<paramname="scriptable"value="false">

</object>)

目前所做的项目是基于JAVAEE的应用,需要在客户端进行文档扫描并提交到客户端

进行进一步处理,如进行OCR文字识别,建立基于内容检索的索引创建等应用。

目前能用的反应普遍比较好的是ScanOnWeb控件,做到确实比较好,好处就不再细说。,

但我试用完后发现的缺点如下:

1.收费,虽说不贵,但对比较大的管理规范的公司,由于售后服务产品保障方面,购买审批难。

2.通用性并不好,同样是遵循Twain协议的扫描仪器,有的扫描仪并不能很好的识别

我用的摄像头,带独立电源的Microtek,和USB供电的Canon进行测试

其中的最新的Canon他无法识别,需要先进入控件的界面然后再插上扫描仪,如果一直

连着扫描仪,将报错。

3.扫描的文件太大了,普通的一页纸张可以达到2M。

由于目前的扫描仪或者摄像头都支持Twain协议,同时也有一个开源的mmsc_tawin工java开发者使用

所以开发基于Applet的扫描仪控件是可行的。

开发步骤如下:

1.基于mmsc_twain开发扫描Applet

2.把mmsc_twain的jar包及相关依赖的jar包中class按

包的结构解压到一个目录下。

3.把这些class打包成一个jar包

3.对这个jar包进行数字签名

4.通过html_conv把html中的applet标签,转换成object

通过以上步骤即可完成在线扫描的控件。

下面代码是通过applet及servlet把扫描的文件

转成PDF格式然后上传到web服务器,进行进一步的文字识别

及基于内容检索。

经过测试,基于applet的在线扫描的优点是硬件识别率高,扫描的文件小,速度快,秉承b/s架构易于维护特性,对java开着者而言最重要的是灵活,

可以自由控制。

缺点也比较明显就是对扫描的文件不能像scanOnWeb那样进行图像的进一步处理。但对于只是简单的纸质文档扫描的应用来说这并不是应用的重点。

如果有需要比较完整的代码的可以继续交流。

======================================================================

代码参考如下:

(htmlConvert,及jar包的数字签名,mmsc_twain的源码网上都可以找到)

测试代码如下:

importjava.applet.Applet;

importjava.awt.Button;

importjava.awt.Graphics;

importjava.awt.event.ActionEvent;

importjava.awt.event.ActionListener;

importjava.awt.image.BufferedImage;

importjava.awt.print.PrinterException;

importjava.io.BufferedWriter;

importjava.io.ByteArrayInputStream;

importjava.io.ByteArrayOutputStream;

importjava.io.DataInputStream;

importjava.io.DataOutputStream;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.io.OutputStreamWriter;

importjava.net.HttpURLConnection;

importjava.net.URL;

importjava.net.URLConnection;

importjavax.imageio.ImageIO;

importorg.apache.pdfbox.pdmodel.PDDocument;

importcom.lowagie.text.Document;

importcom.lowagie.text.Font;

importcom.lowagie.text.Image;

importcom.lowagie.text.Paragraph;

importcom.lowagie.text.pdf.PdfWriter;

importuk.co.mmscomputing.device.scanner.Scanner;

importuk.co.mmscomputing.device.scanner.ScannerDevice;

importuk.co.mmscomputing.device.scanner.ScannerIOException;

importuk.co.mmscomputing.device.scanner.ScannerIOMetadata;

importuk.co.mmscomputing.device.scanner.ScannerListener;

publicclassScannerAppletextendsApplet{

Scannerscanner=Scanner.getDevice();

publicvoidinit(){

Buttonbtn=newButton();

btn.setLabel("扫描");

btn.addActionListener(newActionListener(){

publicvoidactionPerformed(ActionEventevent){

System.out.println(event.getActionCommand()+"||"

+event.getSource()+"MouseClick");

try{

scan();

}catch(Exceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

});

add(btn);

}

publicvoidpaint(Graphicsg){

}

privatevoidscan()throwsScannerIOException{

scanner.select();

scanner.addListener(newScannerListener(){

publicvoidupdate(ScannerIOMetadata.Typetype,

ScannerIOMetadatametadata){

System.out.println("*********Type:"+type.msg);

if(type.equals(ScannerIOMetadata.ACQUIRED)){

BufferedImageimage=metadata.getImage();

System.out.println("Haveanimagenow!");

ByteArrayOutputStreamos=newByteArrayOutputStream();

try{

ImageIO.write(image,"jpg",os);

}catch(Exceptione){

e.printStackTrace();

}

//创建PDF

ByteArrayOutputStreambop=createPDF(os);

//文件上传

upLoad(bop);

}elseif(type.equals(ScannerIOMetadata.NEGOTIATE)){

ScannerDevicedevice=metadata.getDevice();

/**

try{

device.setShowUserInterface(true);

device.setShowProgressBar(true);

device.setResolution(100);

}catch(Exceptione){

e.printStackTrace();

}

***/

}elseif(type.equals(ScannerIOMetadata.STATECHANGE)){

System.err.println(metadata.getStateStr());

if(metadata.isFinished()){

BufferedImageimage=metadata.getImage();

System.out.println("###//Haveanimagenow!");

}

}elseif(type.equals(ScannerIOMetadata.EXCEPTION)){

metadata.getException().printStackTrace();

}

}

});

scanner.acquire();

}

privateByteArrayOutputStreamcreatePDF(ByteArrayOutputStreamos){

Documentdocument=newDocument();

ByteArrayOutputStreambop=newByteArrayOutputStream();

try{

PdfWriter.getInstance(document,bop);

//PdfWriter.getInstance(document,newFileOutputStream(

//"E:/study/applet/TestPDF.PDF"));

document.open();

//Fontfnt=newFont();

//document.add(newParagraph("loadatifimagefile"));

Imageimg=Image.getInstance(os.toByteArray());

//img.setWidthPercentage(100);

document.addAuthor("EmrArchiveApplication");

document.addCreationDate();

document.addCreator("iTextlibrary");

document.addTitle("ScannerImg");

document.add(img);

//PDDocumentpdoc=PDDocument.load(newFile(

//"E:/study/applet/TestPDF.PDF"));

//

//pdoc.print();

}catch(Exceptione){

System.err.println(e.getMessage());

}

document.close();

returnbop;

}

privatevoidupLoad(ByteArrayOutputStreampdf){

try{

URLConnectioncon=getConnection();

FileOutputStreamfo=newFileOutputStream("C:/archive/APT.pdf");

fo.write(pdf.toByteArray(),0,pdf.toByteArray().length);

fo.close();

OutputStreamos=con.getOutputStream();

DataOutputStreamds=newDataOutputStream(os);

ds.write(pdf.toByteArray());

ds.flush();

//关闭发送流,提交数据

ds.close();

//调用HttpURLConnection连接对象的getInputStream()函数,

//将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。

InputStreamis=con.getInputStream();//<===注意,实际发送请求的代码段就在这里

System.out.println("###EEEEEE");

}catch(IOExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

privatestaticHttpURLConnectiongetConnection()throwsIOException{

URLurl=newURL(

"http://127.0.0.1:8090/emr-archive-app/PDFScanerServlet");

HttpURLConnectioncon=(HttpURLConnection)url.openConnection();

//设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在

//http正文内,因此需要设为true,默认情况下是false;

con.setDoOutput(true);

//设置是否从httpUrlConnection读入,默认情况下是true;

con.setDoInput(true);

//Post请求不能使用缓存

con.setUseCaches(false);

//设定传送的内容类型是可序列化的java对象

//(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)

con.setRequestProperty("Content-Type","application/octet-stream");

//设定请求的方法为"POST",默认是GET

con.setRequestMethod("POST");

returncon;

}

publicstaticvoidmain(String[]avs)throwsIOException{

FileInputStreamfi=newFileInputStream("C:/archive/BH.pdf");

ByteArrayOutputStreambo=newByteArrayOutputStream();

intindex=0;

byte[]tmp=newbyte[1024];

while((index=fi.read(tmp))>-1){

bo.write(tmp,0,index);

};

newScannerApplet().upLoad(bo);

}

}

相关推荐