1.注意事項
1.網頁對攝像頭呼叫的限制比較高,要求網頁必須https協議或者是要本地localhost(127.0.0.1)否則無法呼叫,
2.當你的網頁協議是https請求的時候你向後端伺服器發的請求也是要https協議,否則也會出問題。
3.該專案是根據一個拍照識別商品並且展示3d產品的程式碼改的,有些東西看不懂可以無需理會。
2. 案例地址
案例地址
3. 前端全部程式碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>攝像頭拍照</title>
</head>
<style>
body, html {
margin: 0;
height: 100%;
}
video {
width: 100%;
display: block;
}
#capture {
position: absolute;
top: 50%;
left: 30px;
transform: translateY(-50%);
z-index: 2;
font-weight: bold;
font-size: 24px;
opacity: 0.3;
padding: 10px 20px;
cursor: pointer;
}
canvas {
display: block;
}
#lookModel {
position: absolute;
top: 50%;
left: 50px;
font-size: 50px;
padding: 10px 20px;
cursor: pointer;
border-radius: 10px;
border: solid 0px;
opacity: 0.5;
transform: translateY(-50%);
display: none;
}
</style>
<body>
<div style="width: 600px; position: relative;">
<button id="capture">拍照</button>
<video id="video" style="width: 600px; position: relative;">
</video>
</div>
<div id="html" style="position: absolute; top: 30px; right: 50px;">
</div>
<div style="display: block; position: relative;" id="none">
<canvas id="canvas" width="480" height="320">
</canvas>
<button id="lookModel">模型混合現實</button>
</div>
<script src="./js/jquery-1.11.0.min.js"></script>
<script>
document.getElementById('lookModel').onclick = function (ev) {
location.href = './gltf.html'
}
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
navigator.webkitGetUserMedia(constraints, success, error)
} else if (navigator.mozGetUserMedia) {
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
navigator.getUserMedia(constraints, success, error);
}
}
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
function success(stream) {
let CompatibleURL = window.URL || window.webkitURL;
console.log(stream);
video.srcObject = stream;
video.play();
}
function error(error) {
console.log(`訪問使用者媒體裝置失敗${error.name}, ${error.message}`);
}
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
getUserMedia({video: {width: 480, height: 320}}, success, error);
} else {
alert('不支援訪問使用者媒體');
}
document.getElementById('capture').addEventListener('click', function () {
context.drawImage(video, 0, 0, 480, 320);
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
setTimeout(() => {
send()
}, 300)
})
function dataURItoBlob(base64Data) {
var byteString;
if (base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);
else
byteString = unescape(base64Data.split(',')[1]);
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type: mimeString});
};
function blobToFile(theBlob, fileName) {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
};
function send() {
var base64Data = canvas.toDataURL("image/jpeg", 1.0);
var blob = dataURItoBlob(base64Data);
var file = blobToFile(blob, "imgSignature");
var data = new FormData();
data.append("file", file);
function ajax() {
$.ajax({
url: "http://localhost:3000/image2",
type: "POST",
dataType: "JSON",
data: data,
contentType: false,
processData: false,
success: function (res) {
let i = 0
console.log(res);
if (res.result.length == 0) return ajax()
if (res.result[0].score > 0.6) {
document.getElementById('lookModel').style.display = 'block'
console.log('111: ', 111)
} else {
document.getElementById('lookModel').style.display = 'none'
console.log('222: ', 222)
}
document.getElementById('none').style.display = "block"
let html = ""
res.result.forEach((val) => {
html += `${++i} 檔名:***${Math.round(Math.random() * 10000)}****<br>相似度:${val.score}<br><br> `
})
$("#html").html(html)
}, error(error) {
console.log('error: ', error)
}
});
}
ajax()
}
</script>
</body>
</html>
4. java後端全部程式碼(maven工程專案)
伺服器配置
server:
port: 3000
devtools:
restart:
enabled: true
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ImageApplication {
public static void main(String[] args) {
SpringApplication.run(ImageApplication.class,args);
}
}
@RestController
public class UploadController {
@Autowired
private UploadService uploadService;
@PostMapping("/image2")
public ResponseEntity<String> uploadImage(MultipartHttpServletRequest request) throws IOException {
MultipartFile file = request.getFile("file");
String resultUrl;
byte[] bytes = file.getBytes();
resultUrl = uploadService.uploadImage( bytes, ".png");
return ResponseEntity.ok(resultUrl);
}
}
import ch.qos.logback.core.util.TimeUtil;
import com.mq.image.search.SimilarSearch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@Service
public class UploadService {
public String uploadFileToNginx2(byte[] file, String fix) {
String ROOT_PATH = "D:\\deptuploadImage\\";
File targetFile = new File(ROOT_PATH);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
FileOutputStream out = null;
String fileName = "test";
try {
out = new FileOutputStream(ROOT_PATH + fileName + fix);
out.write(file);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return fileName + fix;
}
public String uploadImage(byte[] file, String fix) {
String path = uploadFileToNginx2(file, fix);
return path;
}
}