扫描控件Web在线Applet
基于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);
}
}
扫描控件Web在线Applet的更多相关文章
- 整理部分JS 控件 WEB前端常用的做成Jsp项目,方便今后直接用
整理部分JS 控件 WEB前端常用的做成Jsp项目,方便今后直接用 最近又没时间了,等用时间了,再加入更多的, 源码下载: http://download.csdn.net/detail/liang ...
- 使用图像扫描控件ScanOnWeb实现在线图像扫描
今天上网查资料,看到一篇文章,描述的是一个开发OA软件的公司解决浏览器嵌入式扫描仪编程的文章,文章描述了改OA厂商的工程师如何辛苦的克服了各种技术难题,最终实现了在线图像扫描处理,然后又在无数个不眠的 ...
- 基于纯前端类Excel表格控件实现在线损益表应用
财务报表也称对外会计报表,是会计主体对外提供的反映企业或预算单位一定时期资金.利润状况的会计报表,由资产负债表.损益表.现金流量表或财务状况变动表.附表和附注构成.财务报表是财务报告的主要部分,不包括 ...
- ChinaCock扫描控件介绍-使用TCCBarcodeScanner引起app闪退
好几个ChinaCock的朋友说遇到扫码时闪退,进一步总结,都是Android 8的机器上才会出现,今天我也遇到.正好有朋友说,按下面这个改配置文件就可以解决: <!-- 扫描的activity ...
- iOS 简单易用的二维码扫描及生成二维码三方控件LFQRCode,可灵活自定义UI
一.扫码 扫描的控件是一个view,使用者只需贴在自己的控制器内即可.其他UI用户可在自己控制器随便添加.代码如下 - (void)viewDidLoad { [super viewDidLoad]; ...
- .NET中使用GridView控件输入数据时出现“ Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"的问题
在.NET中使用GridView控件的在线编辑数据时,出现了“ Index was out of range. Must be non-negative and less than the size ...
- asp.net ajax控件tab扩展,极品啊,秒杀其它插件
说明:asp.net ajax控件tab要设置width和height,而且在线文本编辑器放能够放入tab中,也必须是asp.net的控件型在线文本,例如fckeditor,下面是我设置好的配置. & ...
- atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系
atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系 1. server控件是要server了解了标签.种类型的server控件: 1 1. ...
- 方法控件[置顶] Asp.net总结(一)
本文朋友在青岛逛街的时候突然想到的...这两天就有想写几篇关于方法控件的博客,所以回家到之后就奋笔疾书的写出来发表了 纵观 Asp.net的学习只会之路,可以发现 Asp.net可以分为以下几大块 控 ...
随机推荐
- Android(java)学习笔记167:横竖屏切换时Activity的生命周期
1.横竖屏切换的生命周期 默认情况下横竖屏切换,先销毁再创建 2.有的时候,默认情况下的横竖屏切换(先销毁再创建),对应用户体验是不好的,比如是手机游戏横竖屏切换对游戏体验非常不好,下面两种方 ...
- tomcat 安全配置文档
1.配置文档中使用$CATALINA_HOME变量声明为tomcat的安装目录并明确写出了tomcat的配置文件路径,此路径为测试环境的路径,线上系统对应配置文件的路径可能不一样,在进行相关配置时,应 ...
- webpack打包 css文件里面图片路径 替换位置
{ test: /\.css$/, use: ExtractTextPlugin.extract({ use: ['css-loader?minimize', 'autoprefixer-loader ...
- regular expression matching DP
这个题目,我从前天晚上(8月6号晚上)调试到现在(8月8号16:21),太心酸了,不好好总结一下,就太对不起自己了! 这是题目: Implement regular expression matchi ...
- python3查询Excel中A表在B表没有的数据,并保存到新的Excel,这里用的是“xlrd”和“xlwt”
import xlrd import xlwt # 打开A表,将A表的数据存放到cols1中,这里打印出来是方便查看测试数据. data1 = xlrd.open_workbook(r'F:\cars ...
- DNS查询过程
DNS查询过程 假设www.abc.com的主机要查询www.xyz.abc.com的服务器ip地址. 知识点 1.hosts文件:以静态映射的方式提供IP地址与主机名的对照表,类似ARP表 2.域: ...
- ZOJ - 3781 Paint the Grid Reloaded 题解
题目大意: 给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色. 思路: 1. ...
- HDU 4418 高斯消元解决概率期望
题目大意: 一个人在n长的路径上走到底再往回,走i步停下来的概率为Pi , 求从起点开始到自己所希望的终点所走步数的数学期望 因为每个位置都跟后m个位置的数学期望有关 E[i] = sigma((E[ ...
- CSU 1290 DP解决数学期望问题
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1290 题目大意: 给定k个数,每次可以生成0-N-1中的任何一个数,k个数中出现不同的整 ...
- CSU1350 To Add which?
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1350 这题目因为每一个数都跟相邻的数有关,所以可以从左到右和从右到左一次扫一遍即可 代 ...