HTML5手機端拍照上傳
阿新 • • 發佈:2018-12-30
最近在嘗試做手機端拍照上傳的專案,之前用微信JS-SDK 發現有時候上傳照片會有問題,下載後的照片只有一半。所以改用了HTML5上傳,在做這一點上傳中也學習了一下JS和HTML5的一些標籤。記錄一下。
首先需要在頁面新增HTML5控制元件 capture="camera" 這樣就可以在android5.0 或則 IOS 9.0 以上直接拉起照相機,但是這些版本之下的手機只能呼叫相簿選擇
<input type="file" capture="camera" accept="image/*" id="imgcamera" name="imgcamera" style="display: none;" onchange="ImgChange(this)">
另外需要新增3個js控制元件
<script src="md5.js"></script> //圖片上傳校驗
<script src="exif.js"></script> //照相後自動旋轉 這個很有用
<script src="cvi_busy_lib.js"></script> //正在上傳的遮蓋層
開啟攝像頭程式碼如下
//拍照 function cameraImg() { document.getElementById("imgcamera").value = ""; //上傳檔案時先把file型別input清空下 $("input[id='imgcamera']").click(); }
拍照後圖片處理程式碼如下,主要是先做圖片旋轉,有些手機拍照後顯示圖片是偏轉的,需要自己先調整正確角度,在進行圖片縮放,最後是壓縮處理。
function ImgChange(imgdata) { var _this = imgdata, _file = _this.files[0], fileType = _file.type; console.log(_file.size); //圖片方向角 added by lzk var Orientation = ""; if (/image\/\w+/.test(fileType)) { EXIF.getData(_file, function () { EXIF.getAllTags(this); Orientation = EXIF.getTag(this, 'Orientation'); }); var fileReader = new FileReader(); fileReader.readAsDataURL(_file); fileReader.onload = function (event) { var result = event.target.result; //返回的dataURL var image = new Image(); image.src = result; image.onload = function () { //建立一個image物件,給canvas繪製使用 var cvs = document.createElement('canvas'); var scale = 1; if (this.width > 1080 || this.height > 1080) { //1080只是示例,可以根據具體的要求去設定縮放圖片大小 if (this.width > this.height) { scale = 1080 / this.width; } else { scale = 1080 / this.height; } } cvs.width = this.width * scale; cvs.height = this.height * scale; //計算等比縮小後圖片寬高 var ctx = cvs.getContext('2d'); ctx.drawImage(this, 0, 0, cvs.width, cvs.height); var imgtmp = new Image(); imgtmp.src = cvs.toDataURL(fileType, 0.8); imgtmp.onload = function () { var cvstmp = document.createElement('canvas'); var isori = false; if (Orientation != "" && Orientation != 1) { //alert('旋轉處理' + Orientation); switch (Orientation) { case 6://需要順時針(向左)90度旋轉 //alert('需要順時針(向左)90度旋轉'); isori = true; rotateImg(this, 'left', cvstmp); break; case 8://需要逆時針(向右)90度旋轉 //alert('需要順時針(向右)90度旋轉'); rotateImg(this, 'right', cvstmp); isori = true; break; case 3://需要180度旋轉 //alert('需要180度旋轉'); rotateImg(this, 'right', cvstmp);//轉兩次 rotateImg(this, 'right', cvstmp); isori = true; break; } } var newImageData; if (isori) newImageData = cvstmp.toDataURL(fileType, 0.8); //重新生成圖片,fileType為使用者選擇的圖片型別 else newImageData = imgtmp.src; var sendData = newImageData.replace("data:" + fileType + ";base64,", ''); $("#img" + imageType1).attr("src", newImageData); //顯示圖片 var md5str = hex_md5(sendData); //MD5校驗 uploadImages(sendData, md5str); } } } } else { alert("圖片型別不正確"); } }
選擇圖片的程式碼如下
function rotateImg(img, direction, canvas) {
//alert(img);
//最小與最大旋轉方向,圖片旋轉4次後回到原方向
var min_step = 0;
var max_step = 3;
//var img = document.getElementById(pid);
if (img == undefined) return;
//img的高度和寬度不能在img元素隱藏後獲取,否則會出錯
var height = img.height;
var width = img.width;
var step = 2;
if (direction == 'right') {
step++;
//旋轉到原位置,即超過最大值
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
var ctx = canvas.getContext('2d');
//旋轉角度以弧度值為引數
var degree = step * 90 * Math.PI / 180;
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
return ctx;
}
最後是上傳伺服器的程式碼
//將圖片上傳的伺服器本地
function uploadImages(localData, md5str) {
var xval = getBusyOverlay('viewport', {
color: 'white',
opacity: 0.75,
text: 'viewport: loading...',
style: 'text-shadow: 0 0 3px black;font-weight:bold;font-size:16px;color:white'
}, {color: '#ff0', size: 100, type: 'o'});
$.ajax({
type: "POST",
url: "",
beforeSend: function () {
if (xval) {
xval.settext("正在上傳圖片,請稍後......");//此處可以修改預設文字,此處不寫的話,就按照預設文字來。
}
},
data: {
localData: localData,
md5str: md5str
},
dataType: "json",
timeout: 120000, //超時時間:120秒
success: function (data) {
xval.remove(); //此處是移除遮罩層
if (data.result == 1) {
alert("上傳成功!");
} else {
alert("上傳失敗!");
}
}, error: function (XMLHttpRequest, textStatus, errorThrown) {
xval.remove(); //此處是移除遮罩層
alert("上傳失敗!");
}
});
}
後臺程式碼就不貼出來了可以使用各種語音接收,由於初次接觸html5 所以程式碼寫的比較亂。如有不對希望大家指正。