有時候,我們不想通過上傳本地圖片的方式上傳圖片,而是通過相機拍照,將這個拍照后的圖片直接上傳到服務器上,不需要保存到本地。
比如,用video模擬一個攝像頭,通過webrtc調用攝像頭的方式拍一張照,然后通過canvas通過getContext('2d')獲取的繪圖對象CanvasRenderingContext2D
的drawImage(video, x, y, width, heigth)
方法將video圖像通過canvas直接畫到html頁面上,用來呈現拍照后的結果。
通常的做法是用
<input type="file"/>
的方式上傳圖片的。但這種方式是要求圖片具體存在的,本地或者url路徑上的。
現在我們來通過canvas的toDataURL或者toBlob方法、File對象、FormData對象來通過ajax上傳圖片。
<video id="video"></video>
<canvas id="canvas"></canvas>
<script type="text/javascript">
// 調用攝像頭的代碼省略...
let video = document.querySelector('#video')
let canvas = document.querySelector('#canvas')
let context = canvas.getContext('2d')
context.drawImage(video, 0, 0, 300, 150) // 將video標簽的圖片畫到canvas上
// 正片開始
// 通過canvas調用toBlob方法獲取blob對象,傳入一個回調函數,這個回調函數的參數就是blob對象
let s = canvas.toBlob(function (blob) {
/*
* 注意第一個File的構造方法第一個參數必須要用[]包起來,表明這是一個數組
* 第二個參數是這個文件名
* 第三個參數是選項,其中通過type指定這個文件的mime值
*/
let file2 = new File([blob], 'a.jpg', {type: 'image/jpg'})
// ajax上傳文件不能像上傳普通對象那樣,得用上FormData
let formData = new FormData()
formData.append('file', file2)
$.ajax({
url: '/a', // 后台接口
type: 'POST',
processData: false, // processData和contentType必須指定為false
contentType: false,
cache: false,
data: formData,
success(res) {
console.log("上傳完成!")
}
})
});
</script>
第二種方式,通過base64轉碼,這里只看js代碼
這是canvas調用toDataURL方法將圖片base64編碼
let base64 = canvas.toDataURL(); // 同樣通過canvas的toDataURL方法將canvas圖片Base64編碼
let bstr = atob(base64.split(',')[1]); // atob是將base64編碼解碼,去掉data:image/png;base64,部分
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
// 寫法同上
let file2 = new File([u8arr], 'a.jpg', {type: 'image/jpg'})
let formData = new FormData()
formData.append('file', file2)
console.log(formData)
$.ajax({
url: '/a',
type: 'POST',
processData: false,
contentType: false,
cache: false,
data: formData,
success(res) {
console.log("上傳完成!")
}
})
其上兩種寫法皆可
下面是后台代碼,這里用的是java
@Controller
public class IndexCtronller {
@RequestMapping(value = "/a", method = RequestMethod.POST)
public ResponseEntity index(MultipartFile file) { // 通過MultipartFile對象接收文件
String contextPath = "C:\\Users\\dagger\\Desktop"; // 上傳文件路徑
File file1 = new File(contextPath, "a.jpg");
try {
file.transferTo(file1); // 將文件保存到服務器桌面
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}