因為最近一段時間,一直在弄微信項目,其中涉及到了證件上傳的功能,剛開始的時候一點頭緒都沒有,上網查了很多資料,QQ群裡面也問了不少人,很多人說如果是app程式,可以申請系統許可權,然後再去調用系統底層的東西,但是微信是在瀏覽器裡面操作的,我們自訂的頁面也是通過微信內建瀏覽器開啟的,而且微信瀏覽器在內部進行了很多特殊處理,屏蔽了很多東西,所以要在頁面調用拍照功能或者是開啟手機系統的圖庫目錄是不可能的,當然,這些都只是大伙兒理論上的猜測而已,而在我查了兩天的資料之後,發現這個問題原來是可以解決的,而且實現的過程居然也很簡單。只是用到了HTML5的file檔案上傳功能,再配合canvas即可。下面附上原始碼:
<span style="font-family:KaiTi_GB2312;font-size:14px;"><!DOCTYPE html>
<html>
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=yes">
<head>
<meta charset="UTF-8">
<title>上傳證件</title>
<style>
body {
margin: 20px 20%;
color:#777;
text-align: center;
}
#result{
margin-top: 20px;
}
</style>
</head>
<body>
<h1>上傳證件...</h1>
<hr/>
<input type="file"/>
<div id="result"></div>
<hr/>
<!-- 引入jQuery -->
<script type="text/javascript" src="../js/jQuery/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="../js/LocalResizeIMG.js"></script>
<!-- mobileBUGFix.js 相容修複行動裝置 -->
<script src="../js/mobileBUGFix.mini.js" type="text/javascript"></script>
<script type="text/javascript">
$("input:file").localResizeIMG({
width: 500,
quality: 0.8,
success: function (result) {
var img = new Image();
img.src = result.base64;
console.log(result.clearBase64);
//$("body").append(img);
$("#result").empty();
$("#result").append(img); //呈現映像(拍照?果)
$.ajax({
url: "upLoadImageServlet",
type: "POST",
data:{formFile:result.clearBase64},
dataType: "HTML",
timeout: 1000,
error: function(){
alert("Error loading PHP document");
},
success: function(result){
//alert(result);
//console.log(result);
alert("Uploads success~")
}
});
}
});
</script>
</body>
</html></span>
上面實現的流程導致是這樣的,首先在前端把圖片進行壓縮,因為手機的不同,可能有的手機拍照給力,像素高,拍出來的圖片的大小就相對大一些,所以這裡通過一個外掛程式進行了壓縮,然後轉換成為Base64的編碼,再把Base64的編碼使用AJAX來POST到伺服器,然後在Java或者PHP後台進行Base64解碼,解出來的路徑即為上傳圖片的路徑地址,然後再進行儲存,寫到檔案或者資料庫裡面。
此外,這裡需要說明一個問題:很多人都說到了微信內建瀏覽器,之前我也一直認為微信內建瀏覽器就是微信自己開發的一套瀏覽器,然後對很多東西進行了限制。其實不是這樣的,微信本身並沒有再重新開發一套瀏覽器,而是調用的系統自身的瀏覽器,是根據手機的不同系統而變化的。微信內建瀏覽器調用的是手機系統預設瀏覽器,ios和Android系統預設瀏覽器都是webkit核心,只是對HTML5和CSS3的支援程度可能不同。因為瀏覽器只是系統的一部分,因此系統預設瀏覽器不會單獨升級,對HTM5、CSS3的支援程度與系統版本有很大關係。安卓版微信直接調用系統瀏覽器核心, iOS則是調用safari,大家可以看到下面1和3的效果是一模一樣的,1是微信瀏覽器開啟的,3則是魅族MX 3內建的系統瀏覽器開啟的效果。
上面我的我都測試過了,可以正常運行。下面附上幾張照片:
1、這是在微信裡面開啟的效果
2、這是在手機UC瀏覽器開啟的效果:
3、這個是在系統內建瀏覽器裡面開啟的效果(ps:My Phone是魅族MX 3),但是這個不是開啟系統圖庫目錄,而是直接定位到了系統的檔案夾根目錄。
1、前台js代碼:
$.ajax({
async:false,//是否非同步
cache:false,//是否使用緩衝
type: "POST",
data:{fileData:fileData,licenceName:licenceName,cust_tax_code:cust_tax_code,phoneNum:phoneNum,state_id:state_id},
dataType: "json",
timeout: 1000,
contentType : 'application/x-www-form-urlencoded; charset=utf-8',
url: $('#ctx').val()+"CustomerCheckServlet?action=uploadLicence",
success: function(result){
console.log(result);
if(result == true){
alert('Success Upload~~~');
}else if(result == false){
alert('Error Upload~~~');
}
},
error: function(){
alert("Error Linking~");
}
});
2、後台Java代碼
/**
* 證件上傳
* @param request
* @param response
* @throws IOException
*/
public void uploadLicence(HttpServletRequest request,HttpServletResponse response) throws IOException{
log.info("=====================uploadLicence");
df = new SimpleDateFormat("yyyy-MM-dd");
String cust_tax_code = request.getParameter("cust_tax_code");
String phoneNum = request.getParameter("phoneNum");
String licenceName = request.getParameter("licenceName");
String fileData = request.getParameter("fileData");//Base64編碼過的圖片資料資訊,對位元組數組字串進行Base64解碼
String imgPath = uploadFile(fileData,liceneName);//進行檔案上傳操作,上傳到伺服器中存放(這裡是上傳到伺服器專案檔夾中存到)
boolean result = false;//最終上傳成功與否的標誌
custCheckInfo = new CustomerCheckInfo();
custCheckInfo.setCust_tax_code(cust_tax_code);
custCheckInfo.setPhonenum(phoneNum);
custCheckInfo.setUpdate_time(df.format(new Date()));
boolean save_flag = customerService.saveRegistCertInfo(custCheckInfo);//儲存路徑
//判斷資料庫中的路徑是否存在,並且檔案夾中的檔案是否存在(判斷是否上傳成功的標誌)
boolean is_success = isSuccessUpload(licenceName, cust_tax_code, phoneNum);
if(save_flag && is_success){
result = true;
}
//如果證件上傳成功,則記錄到記錄表中
if(result){
StateRecordInfo record = new StateRecordInfo();
record.setCust_tax_code(cust_tax_code);
record.setPhonenum(phoneNum);
record.setState_id(state_id);
saveStateRecord(record);//執行狀態儲存操作
}
System.out.println("===result:"+result);
PrintWriter pw = response.getWriter();
pw.print(result);
pw.close();
}
/**
* 檔案上傳
* @param fileData
* @param fileName
* @return
*/
public String uploadFile(String fileData,String fileName){
//在自己的項目中構造出一個用於存放使用者照片的檔案夾
String imgPath = this.getServletContext().getRealPath("/uploads/");
//如果此檔案夾不存在則建立一個
File f = new File(imgPath);
if(!f.exists()){
f.mkdir();
}
//拼接檔案名稱,不存在就建立
imgPath = imgPath + "/" + fileName + ".jpg";
f = new File(imgPath);
if(!f.exists()){
f.mkdir();
}
log.info("====檔案儲存的位置:"+imgPath);
//使用BASE64對圖片檔案資料進行解碼操作
BASE64Decoder decoder = new BASE64Decoder();
try {
//通過Base64解密,將圖片資料解密成位元組數組
byte[] bytes = decoder.decodeBuffer(fileData);
//構造位元組數組輸入資料流
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
//讀取輸入資料流的資料
BufferedImage bi = ImageIO.read(bais);
//將資料資訊寫進圖片檔案中
ImageIO.write(bi, "jpg", f);// 不管輸出什麼格式圖片,此處不需改動
bais.close();
} catch (IOException e) {
log.error("e:{}",e);
}
return imgPath;
}
/**
* 判斷是否成功上傳
* @return
*/
public boolean isSuccessUpload(String licenceName,String cust_tax_code,String phonenum){
boolean flag = false;
String licencePath = "";//證件圖片上傳成功之後儲存的路徑
custCheckInfo = customerService.getCustomerCheckInfo(cust_tax_code, phonenum);
licencePath = custCheckInfo.getTax_regist_cert();
//判斷證件路徑不為空白並且在上傳存放的檔案夾中存在,就表明以上傳成功
File f = new File(licencePath);
if(licencePath.length() >0 && f.exists()){
flag = true;
}
return flag;
}
好了,到這裡就全部結束了,這就是HTML5+jQuery+Canvas調用手機拍照功能實現圖片上傳的全部實現過程,總感覺自己的思路有些混亂,嗯,慢慢進步吧!
外掛程式地址:https://github.com/think2011/LocalResizeIMG