开发环境:Windows7系统
高拍仪品牌:汉王(型号忘了。。。)
开发工具:MyEclipse8.5,JDK1.7,MySQL5.0,Tomcat6.0
框架结构:Struts1和JDBC
浏览器:360浏览器或IE浏览器,Chrome不支持该高拍仪插件。
高拍仪二次开发
首先,看下所用的高拍仪是什么品牌,什么型号,找到厂家的联系方式,管客服要高拍仪二次开发的demo,在机器上运行demo,运行好使后,开始建项目,进行高拍仪二次开发。
在MyEclipse里建一个web工程,在工程上右键,选择MyEclipse,然后选择Struts1框架,之后导入jar包,把基础环境搭建好。工程编码选utf-8。
建立如下目录结构
建好后配置struts-config.xml配置文件,代码如下:
Action如果继承了DispatchAction类,就需要配置parameter="method",通过method去找action里的方法。
path="/login"和jsp里的请求路径.do前路径相对应如<form action="/strutsTree2/login.do">
type 指向action的路径,scope指定作用域
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans />
<global-exceptions />
<global-forwards />
<action-mappings >
<action
parameter="method"
path="/gpyAction"
type="com.chenmei.struts.action.GpyAction"
cancellable="true"
scope="request" >
</action>
</action-mappings>
<!-- 声明该web所使用的资源文件,可以有一个或多个,parameter指定资源文件文字或名称 -->
<message-resources parameter="com.chenmei.struts.ApplicationResources" />
</struts-config>
接下来写config.properties配置文件,链接数据,这里用的是mysql。代码如下:
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost:3306/test
uname=root
upass=***
接下来写工具类DbUtils,链接数据库,代码如下:
package com.chenmei.struts.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class DbUtils {
//给自己建一个静态的私有属性
private static DbUtils dl;
//建私有属性
private static String driver;
private static String url;
private static String uname;
private static String upass;
//建一个私有的构造方法,防止随意new它
@SuppressWarnings("static-access")
private DbUtils() throws Exception{
//加载配置文件
Properties p = new Properties();
p.load(this.getClass().getClassLoader().getResourceAsStream("config.properties"));
this.driver = p.getProperty("driver");
this.url = p.getProperty("url");
this.uname = p.getProperty("uname");
this.upass = p.getProperty("upass");
//加载驱动程序到虚拟机中
Class.forName(this.driver);
}
//写一个公有方法,带返回对象,让外边可以new它
public static synchronized DbUtils getInstance() throws Exception{
if(dl == null){
dl = new DbUtils();
}
return dl;
}
//连接数据库对象
public Connection getConnection() throws Exception{
Connection conn = DriverManager.getConnection(url, uname, upass);
return conn;
}
//重载下面的方法
public static void close(ResultSet rs, PreparedStatement ps){
close(rs, ps, null);
}
public static void close(PreparedStatement ps){
close(null, ps, null);
}
public static void close(Connection conn){
close(null, null, conn);
}
//关闭资源方法
public static void close(ResultSet rs, PreparedStatement ps, Connection conn){
if(rs != null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(ps != null){
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(rs != null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
还有一个工具类ResponseUtil用于向页面传输值的,代码如下:
//将结果集输出在页面
public static void write(HttpServletResponse response,Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println(o.toString());
out.flush();
out.close();
}
接下来建一个javabean,映射数据库字段,代码如下:
package com.chenmei.struts.pojo;
public class GpyBean {
private int photo_id;
private String picture;
public int getPhoto_id() {
return photo_id;
}
public void setPhoto_id(int photoId) {
photo_id = photoId;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
}
接下来在mode包里建GpyMode类,代码如下:
package com.chenmei.struts.mode;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.chenmei.struts.utils.DbUtils;
public class GpyMode {
public Connection conn;
private ResultSet rs;
private PreparedStatement ps;
/**
* 插入图片
* @param conn
* @param b
*/
public void insertPicture(Connection conn,byte[] b){
String sql = "INSERT INTO photo (picture) VALUES(?)";
try {
ps = conn.prepareStatement(sql);
InputStream is = new ByteArrayInputStream(b);
ps.setBinaryStream(1,is,b.length);
ps.executeUpdate();
} catch (Exception e) {
System.out.println("插入图片出错!");
e.printStackTrace();
}finally{
DbUtils.close(ps);
}
}
/**
* 查询图片,根据传进来的ID查询出一张图片,因为图片太大,只能一张一张查询,查多张会内存溢出。
*/
public byte[] getImg(Connection conn,String photo_id){
String sql = "SELECT picture FROM photo WHERE photo_id = ?";
byte[] data = null;
try {
ps = conn.prepareStatement(sql);
ps.setString(1, photo_id);
rs = ps.executeQuery();
if(rs.next()){
Blob blob = rs.getBlob("picture");
Long size = blob.length();
data = blob.getBytes(1, size.intValue());
}
} catch (Exception e) {
System.out.println("查询图片出错!");
e.printStackTrace();
}finally{
DbUtils.close(rs, ps);
}
return data;
}
/**
* 查询ID集合
* @param conn
* @param page
* @param rows
* @return
*/
public JSONArray getImgid(Connection conn, int page, int rows) {
JSONArray jsonarray=new JSONArray();
try{
String sql = "SELECT photo_id FROM photo limit ?,? ";
ps=conn.prepareStatement(sql);
ps.setInt(1, (page-1)*rows); //分页公式,算出从第几条开始查询
ps.setInt(2, rows);
rs=ps.executeQuery();
while (rs.next()){
JSONObject obj=new JSONObject();
obj.put("photo_id", rs.getString("photo_id"));
jsonarray.add(obj);
}
}
catch(Exception ex){
System.out.println("获取photo_id集错误");
ex.printStackTrace();
}
return jsonarray;
}
/**
* 获取总数
* @param conn
* @return
*/
public int getTotal(Connection conn){
String sql = "SELECT COUNT(photo_id) AS total FROM photo";
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if(rs.next()){
return rs.getInt(1);
}else{
return 0;
}
} catch (Exception e) {
System.out.println("获取总数出错!");
e.printStackTrace();
}finally{
DbUtils.close(rs, ps);
}
return 0;
}
}
接下来在action包里建一个GpyAction类,代码如下:
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.chenmei.struts.action;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.chenmei.struts.mode.GpyMode;
import com.chenmei.struts.utils.DbUtils;
import com.chenmei.struts.utils.ResponseUtil;
/**
* MyEclipse Struts
* Creation date: 09-13-2017
*
* XDoclet definition:
* @struts.action parameter="method" validate="true"
*/
public class GpyAction extends DispatchAction {
/*
* Generated Methods
*/
/** 在前台获取图片存储的数据库
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward insertPicture(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
String base64 = request.getParameter("base64");//前台64位编码
Connection conn = null;
boolean result = false;
try {
conn = DbUtils.getInstance().getConnection();
GpyMode gpyMode = new GpyMode();
byte[] b = decodeBase64(base64);
gpyMode.insertPicture(conn, b);
result = true;
ResponseUtil.write(response, result);
} catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.close(conn);
}
return null;
}
/**
* 查询图片,根据传进来的photo_id查询出一张图片,因为图片太大,只能一张一张查询,查多张会内存溢出。
*/
public ActionForward getImg(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
Connection conn=null;
try {
conn = DbUtils.getInstance().getConnection();
GpyMode gpyMode = new GpyMode();
String photo_id = String.valueOf(request.getParameter("photo_id"));
byte[] img = gpyMode.getImg(conn,photo_id);
response.setContentType("image/jpeg");
OutputStream outs = response.getOutputStream();
outs.write(img);
} catch (Exception e) {
e.printStackTrace();
}
finally{
DbUtils.close(conn);
}
return null;
}
/**
* 查询图片ID集合,总记录数,总页数
* @param mapping
* @param form
* @param request
* @param response
* @return
*/
public ActionForward getImgId(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
Connection conn = null;
int pageNum = 0;
try {
int page=Integer.valueOf(request.getParameter("page")==null? "1":request.getParameter("page"));
int rows=Integer.valueOf(request.getParameter("rows")==null? "20":request.getParameter("rows"));
JSONObject result = new JSONObject();
conn = DbUtils.getInstance().getConnection();
GpyMode gpyMode = new GpyMode();
int total = gpyMode.getTotal(conn);
JSONArray jsonarray=gpyMode.getImgid(conn,page,rows);
if(total%rows==0){
pageNum = total/rows;
}else{
pageNum = total/rows+1;
}
result.put("total", total);
result.put("pageNum", pageNum);
result.put("jsonarray", jsonarray);
ResponseUtil.write(response, result);
} catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.close(conn);
}
return null;
}
/***
* 64位转化成byte数组
* @param input
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static byte[] decodeBase64(String input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("decode", String.class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, input);
return (byte[])retObj;
}
}
后台写完了,接下来写jsp,在jsp里我把demo里的代码拷贝了过来,但是只做了加载摄像头,拍照,分页,图片旋转等功能,如果下载了源码,需要把显示大图处调整一下,index.jsp代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>汉王高拍仪样例</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="js/jquery-1.11.2.min.js"></script>
<!-- 图片旋转的引用文件 -->
<link rel="stylesheet" type="text/css" href="/hw_gpy/css/bootstrap.css">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
/*打开页面时加载高拍仪摄像头 仿照汉王高拍仪给的WebDemo里的如下代码
var idx = 0;
function plugin0()
{
return document.getElementById('plugin0');
}
plugin = plugin0;
function start_preview()
{
plugin().OpenCamera(idx);
enumres();
}*/
var idx = 0;
$(function(){
function plugin0(){
return document.getElementById('plugin0');
}
plugin = plugin0;
plugin().OpenCamera(idx);
initImg();//初始化页面时调加载图片的方法,显示图片
})
/* 保存图片 仿照汉王高拍仪给的WebDemo里的如下代码,将其转成64位编码,将base64传到action里处理。
function capbase64(){
var tval = plugin().CaptureBase64(idx);
}*/
function capture(){
var base64 = plugin().CaptureBase64(idx);
$.ajax({
url:"/hw_gpy/gpyAction.do?method=insertPicture",
type:"post",
data:{"base64":base64},
dataType:"json",
success:function(result){
$("#img_list").empty();
initImg();
alert("保存成功");
},
error:function(result){
alert("保存失败!");
}
});
}
/**显示一张图片时,向后台传入一个ID,如photo_id=1,根据ID控制where条件,在后台查询一张图片显示,图片太大,查询多张会内存溢出。
function initImg(){
var img = "<img id=img src=/hw_gpy/gpyAction.do?method=getImg&photo_id=1 height='80px' width='100px' />"
$("#img_list").append(img);
}*/
//分页加载图片
var page = 1;//当前页码
var rows = 2;//每页显示几条
function initImg(){
$.ajax({
url:"/hw_gpy/gpyAction.do?method=getImgId&page="+page+"&rows="+rows,
type:"get",
dataType:"json",
success:function(result){
$.each(result.jsonarray,function(i,n){
var img = "<img id=img"+i+" class='small_img' src=/hw_gpy/gpyAction.do?method=getImg&photo_id="+n['photo_id']+" height='80px' width='100px' class='small_img' />"
$("#img_list").append(img);
});
var total = result.total;
$("#total").val(total);//总记录数
var pageNum = result.pageNum;
$("#pageNum").val(pageNum);//总页数
$("#page").val(page);//当前页码
}
});
}
//下一页
function next(){
page = $("#page").val();
var pageNum = $("#pageNum").val();
if(page!=pageNum){
page++;
$("#img_list").empty();//清空append方法里的内容
initImg();
}else{
alert("最后一页");
}
}
//上一页
function pre(){
page = $("#page").val();
if(page!=1){
page--;
$("#img_list").empty();
initImg();
}else{
alert("第一页");
}
}
//第一页
function first(){
page = 1;
$("#img_list").empty();
initImg();
}
//最后一页
function last(){
page = $("#pageNum").val();
$("#img_list").empty();
initImg();
}
//放大图片预览
function clickImg(){
var source = $('.small_img').attr('src') //缩略图的src属性值
$("#big_img").html("<img id='bigImg' src='"+source+"' height='480px' width='560px' />");
}
</script>
</head>
<body>
<!-- 仿照汉王高拍仪给的WebDemo里的如下代码 -->
<object id="plugin0" type="application/x-dypcap" width="640" height="480">
<param name="onload" value="pluginLoaded" />
</object>
<!-- 显示大图 -->
<div class="col-md-4" id="big_img" style="float: right;margin-right: 500px;"></div>
<br /><br /><br />
<div>
当前设备:<select id="curDev" style="width: 90px" name="selDev"
οnchange="changedev()"></select>
当前分辨率:<select id="curRes" style="width: 90px" name="curRes"
οnchange="changeres()"></select>
颜色:<select id="curColor" style="width: 90px" name="curRes"
οnchange="changeclr()"></select>
裁剪类型:<select id="capMode" style="width: 90px" name="curRes"
οnchange="changemode()"></select>
旋转角度:<select id="rotMode" style="width: 90px" name="curRes"
οnchange="changerotatemode()"></select>
文件类型:<select id="fileType" style="width: 90px" name="curRes"
οnchange="changefiletype()"></select>
<input id="autoExp" type="checkbox" value="" οnclick="" />自动曝光 曝光度<input id="expVal" TYPE="text" VALUE="-4" />
</div>
<br>
<input TYPE="button" VALUE="开始预览" onClick="start_preview()">
<input TYPE="button" VALUE="停止预览" onClick="stop_preview()">
<input TYPE="button" VALUE="视频属性" onClick="showprop()">
<input TYPE="button" VALUE="拍照" onClick="capture()">
<input TYPE="button" VALUE="设置曝光度" onClick="setexp()">
<input TYPE="button" VALUE="设置水印" onClick="setwm()">
<input TYPE="button" VALUE="切换摄像头" onClick="switchcam()">
<input TYPE="button" VALUE="拍照为Base64" onClick="capbase64()">
<input TYPE="button" VALUE="Base64转化为图片" onClick="convertfrombase64()">
<input TYPE="button" VALUE="拍照上传" onClick="capupload()">
<input TYPE="button" id=tmcap VALUE="定时拍照" onClick="timercap()">
<input TYPE="button" id=autocap VALUE="智能连拍" onClick="autocap()">
<!-- 图片预览 -->
<div style="height:30px;margin:20px 0 0 0;">
<input id="first" type="button" value="第一页" οnclick="first()" />
<input id="pre" type="button" value="上一页" οnclick="pre()" />
<!-- 显示缩略图 -->
<span id="img_list" οnclick="clickImg()"></span>
<input id="next" type="button" value="下一页" οnclick="next()" />
<input id="last" type="button" value="最后一页" οnclick="last()" />
当前第 <input id="page" type="text" value="" readonly="readonly" style="width: 24px;"/> 页,
共 <input id="pageNum" type="text" value="" readonly="readonly" style="width: 24px;"/> 页,
共 <input id="total" type="text" value="" readonly="readonly" style="width: 24px;"/> 条记录
<input id="left" type="button" value="左旋转" οnclick="leftRotate()"></input>
<input id="right" type="button" value="右旋转" οnclick="rightRotate()"></input>
</div>
<!-- 图片旋转的引用文件,注意位置 -->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.easing.min.js"></script>
<script type="text/javascript" src="js/jQueryRotate.js"></script>
<script type="text/javascript">
var angle = 0
//图片右旋转(点击按钮旋转)
function rightRotate(){
angle += 90;
$("#bigImg").rotate({
animateTo:angle
});
}
//图片左旋转(一下方法如改成初始化加载,点击图片转动,本例中,先点击按钮在点击图片转动)
function leftRotate(){
$("#bigImg").rotate({
bind:{
click: function(){
angle -=90;
$(this).rotate({ animateTo:angle})
}
}
});
}
</script>
</body>
</html>
接下来,部署工程,就可以运行了。
预览效果图:
源码下载链接:https://pan.baidu.com/s/1eRWOKAu
密码
: jp9x