基于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);

}
}

基于Applet的Web在线扫描仪控件相关推荐

  1. 多比图形控件教程:基于Flex/Javascript的网页绘图控件

    2019独角兽企业重金招聘Python工程师标准>>> 1.概述 多比矢量图控件是一个在Web上绘图的组件,适用于需要在网页中/编辑流程图.图表.网络图和普通矢量图形的Web应用程序 ...

  2. html标签手册 360doc,基于AJAX的文件上传控件NetAdvantage for jQuery

    NetAdvantage for jQuery 是一款全新的轻量级.高性能的jQuery控件,包含了在线的Video播放控件,基于AJAX的文件上传控件,快速且强大的表格控件,以及创建和编辑Word. ...

  3. ATGrid WEB报表打印控件/MIS报表控件

    ATGrid WEB报表打印控件/MIS报表控件 ATGrid报表控件/WEB插件[专业版],对EtCell进行了进行了全面的改革, 将会彻彻底底的解决你的报表问题,让你开发达到从未有过的轻松和喜悦- ...

  4. HTML在线编辑器控件

    经常会在网而上看到一些类似OfficeXP 中的工具条上的按钮和图标,觉得很漂亮,这几天在学习ASP.NET的时候才明白有这么多的HTML在线编辑器控件,如博客园中使用的几种HTML在线编辑器控件: ...

  5. recycleview横向展开_Android开发之基于RecycleView实现的头部悬浮控件

    RecyclerView是一种类似于ListView的一个滑动列表,但是RecyclerView和ListView相比,RecyclerView比ListView更好,RecyclerView支持横向 ...

  6. web元件库、axure元件库、元件库、web组件、控件、表单、框架、数据表单、导航栏、边框、图标、列表、日期时间选择器、评分组件、穿梭框、输入框、步骤条、图表组件、数据可视化、后台模板、时间轴

    web元件库.axure元件库.通用元件库.web组件.控件.表单.框架.数据表单.导航栏.边框.图标.列表.日期时间选择器.评分组件.穿梭框.输入框.步骤条.图表组件.数据可视化.后台模板.时间轴. ...

  7. NTKO在线office控件使用实例

    目录 1. NTKO在线office控件使用实例 1.1. 基础介绍 1.2. 基本原理 1.3. 实例 1.3.1. 打开.保存部分代码 1.3.2. 动态设值 1. NTKO在线office控件使 ...

  8. 无法下载安装Project Web Access ActiveX 控件

    在访问Project Web Access 的时候,若访问项目中心,或者资源中心等,均需要下载相关ActiveX控件,由于IE配置的各不相同,有时可能导致ActiveX控件,无法下载安装.    通常 ...

  9. 通达OA-今日学习:OFFICE文档在线编辑控件与工作流表单手写签章控件的区别是什么?

    NTKOOFFICE文档在线编辑控件,控件提供商为重庆软航科技,使用范围:OA各个模块上传附件(比如文件柜.工作流.公告通知等模块),如果是Office文档,就可以在线编辑或阅读,在线编辑时可以加盖电 ...

最新文章

  1. 普元王葱权:数字化时代需要新一代的大数据应用平台架构
  2. Linux软件安装小结
  3. HDU-2476 String painter 区间DP
  4. 前端学习(2921):vue的事件
  5. ASP.NET MVC View使用Conditional compilation symbols
  6. 激活策略 查询_苹果手机未激活也可能不是原装货,激活过的手机到底能不能买?...
  7. 带电插拔损坏设备原理_USB接口设备可以带电插拔吗?
  8. ESX的VSWITCH坏了,如何转移到新建的虚拟交换机上?
  9. 2019年全国程序员统一考试,现在开始!
  10. Github 插件之 Octotree 报错介绍与解决
  11. Hive | 用sort_array函数解决collet_list列表排序混乱问题
  12. The Beer House 终于运行起来了
  13. 222_emacs lisp car与cdr函数
  14. awl 多线程SYN***工具0.2版[转]
  15. 别人家的思维导图,原来这么画!
  16. fmdb(FMDatabase) 数据库总结
  17. python 三种方法实现删除一个列表里的重复元素
  18. [渝粤教育] 温州职业技术学院 纳税筹划 参考 资料
  19. NPP/VIIRS DNB/SDR影像下载与预处理
  20. html代码编辑器jason,GitHub - 2947721120/jsoneditor: json编辑器

热门文章

  1. java小丑的毕业设计趣事
  2. 计算机高考怎么复习,高考倒计时30天,清北学霸倾情传授高效复习秘籍
  3. 唯美简洁的DEDECMS小清新文章博客/CMS/织梦模板
  4. 生英语视频信息在计算机内表现形式是,计算机专业英语 unit 2 Computer Architecture.ppt...
  5. 附录2 以太坊:下一代智能合约和去中心化应用平台(选译)
  6. TimeStamp的用法
  7. 软件安装(超好用的工具)!!!
  8. 清空回收站后数据如何恢复?
  9. ubuntu硬盘挂载一般方法
  10. php 99乘法表总结