基于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" > <PARAM NAME = CODE VALUE = "com.founder.applet.scan.ScannerApplet.class" > <PARAM NAME = ARCHIVE VALUE = "scanner.jar" > <param name = "type" value = "application/x-java-applet;version=1.5"> <param name = "scriptable" value = "false"> </object>) 目前所做的项目是基于JAVA EE的应用,需要在客户端进行文档扫描并提交到客户端 进行进一步处理,如进行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的源码网上都可以找到) 测试代码如下: import java.applet.Applet; import java.awt.Button; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.awt.print.PrinterException; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import javax.imageio.ImageIO; import org.apache.pdfbox.pdmodel.PDDocument; import com.lowagie.text.Document; import com.lowagie.text.Font; import com.lowagie.text.Image; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfWriter; import uk.co.mmscomputing.device.scanner.Scanner; import uk.co.mmscomputing.device.scanner.ScannerDevice; import uk.co.mmscomputing.device.scanner.ScannerIOException; import uk.co.mmscomputing.device.scanner.ScannerIOMetadata; import uk.co.mmscomputing.device.scanner.ScannerListener; public class ScannerApplet extends Applet { Scanner scanner = Scanner.getDevice(); public void init() { Button btn = new Button(); btn.setLabel("扫描"); btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println(event.getActionCommand() + "||" + event.getSource() + "MouseClick"); try { scan(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); add(btn); } public void paint(Graphics g) { } private void scan() throws ScannerIOException { scanner.select(); scanner.addListener(new ScannerListener() { public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata) { System.out.println("*********Type:"+type.msg); if (type.equals(ScannerIOMetadata.ACQUIRED)) { BufferedImage image = metadata.getImage(); System.out.println("Have an image now!"); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { ImageIO.write(image, "jpg", os); } catch (Exception e) { e.printStackTrace(); } // 创建PDF ByteArrayOutputStream bop = createPDF(os); // 文件上传 upLoad(bop); } else if (type.equals(ScannerIOMetadata.NEGOTIATE)) { ScannerDevice device = metadata.getDevice(); /** try { device.setShowUserInterface(true); device.setShowProgressBar(true); device.setResolution(100); } catch (Exception e) { e.printStackTrace(); } ***/ } else if (type.equals(ScannerIOMetadata.STATECHANGE)) { System.err.println(metadata.getStateStr()); if (metadata.isFinished()) { BufferedImage image = metadata.getImage(); System.out.println("###//Have an image now!"); } } else if (type.equals(ScannerIOMetadata.EXCEPTION)) { metadata.getException().printStackTrace(); } } }); scanner.acquire(); } private ByteArrayOutputStream createPDF(ByteArrayOutputStream os) { Document document = new Document(); ByteArrayOutputStream bop = new ByteArrayOutputStream(); try { PdfWriter.getInstance(document, bop); // PdfWriter.getInstance(document,new FileOutputStream( // "E:/study/applet/TestPDF.PDF")); document.open(); // Font fnt = new Font(); // document.add(new Paragraph("load a tif image file")); Image img = Image.getInstance(os.toByteArray()); // img.setWidthPercentage(100); document.addAuthor("EmrArchiveApplication"); document.addCreationDate(); document.addCreator("iText library"); document.addTitle("ScannerImg"); document.add(img); // PDDocument pdoc = PDDocument.load(new File( // "E:/study/applet/TestPDF.PDF")); // // pdoc.print(); } catch (Exception e) { System.err.println(e.getMessage()); } document.close(); return bop; } private void upLoad(ByteArrayOutputStream pdf) { try { URLConnection con = getConnection(); FileOutputStream fo = new FileOutputStream("C:/archive/APT.pdf"); fo.write(pdf.toByteArray(), 0, pdf.toByteArray().length); fo.close(); OutputStream os = con.getOutputStream(); DataOutputStream ds = new DataOutputStream(os); ds.write(pdf.toByteArray()); ds.flush(); // 关闭发送流,提交数据 ds.close(); // 调用HttpURLConnection连接对象的getInputStream()函数, // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。 InputStream is = con.getInputStream(); // <===注意,实际发送请求的代码段就在这里 System.out.println("###EEEEEE"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static HttpURLConnection getConnection() throws IOException { URL url = new URL( "http://127.0.0.1:8090/emr-archive-app/PDFScanerServlet"); HttpURLConnection con = (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"); return con; } public static void main(String[] avs) throws IOException { FileInputStream fi = new FileInputStream("C:/archive/BH.pdf"); ByteArrayOutputStream bo = new ByteArrayOutputStream(); int index = 0; byte[] tmp = new byte[1024]; while((index = fi.read(tmp))>-1){ bo.write(tmp, 0, index); }; new ScannerApplet().upLoad(bo); } } |
|