对于之前功能的一个优化
在HTML中定义了一些元素和按钮,包括一个用于显示实时摄像头画面的<video>元素、用于预览拍摄照片的<canvas>元素以及拍照、切换摄像头、重拍和上传照片等操作的按钮。
startCamera函数用于开启摄像头,通过getUserMedia方法获取用户的摄像头权限,并将摄像头画面显示在<video>元素中。switchCamera函数用于切换摄像头,通过选择摄像头列表中的某个摄像头,调用startCamera函数重新开启摄像头。getVideoList函数用于获取摄像头设备列表,通过enumerateDevices方法获取所有设备列表,并筛选出视频设备。takePicture函数用于拍照,使用drawImage方法将摄像头画面绘制在<canvas>元素中,同时在<canvas-preview>元素中显示预览图片。reset函数用于重拍,将预览画面和绘制在<canvas>上的照片清空,同时显示拍照按钮。uploadPhoto函数用于上传照片,将拍摄的照片转换成DataURL格式,调用window.opener中的某个函数,并传递照片数据URL作为参数,最后关闭当前窗口。- 最后,在页面加载完成后,调用
getVideoList函数获取摄像头列表,将列表中的摄像头选项添加到<select>元素中供用户选择使用。
这段代码可以作为一个拍照功能的演示示例,并可以根据需要进行修改和扩展。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>拍照</title>
<style type="text/css">
#canvas-preview {
position: absolute;
left: 0;
right: 0;
top: 10px;
margin: auto;
background: white;
display: none;
}
</style>
</head>
<body style="text-align: center; margin: 0;">
<canvas id="canvas" style="position: absolute; top: -5000px;" width="1280" height="960"></canvas>
<video id="video" style="margin: 10px;"></video>
<canvas id="canvas-preview"></canvas>
<button id="takeIt" class="btn" onclick="takePicture()">拍照</button>
<select id="selectCamera" onchange="switchCamera()">
<option value="">请选择摄像头</option>
</select>
<button id="reClear" class="btn" onclick="reset()" style="display: none;">重拍</button>
<button id="upload" class="btn" onclick="uploadPhoto()" style="display: none;">上传</button>
</body>
<script type="text/javascript">
var preview = document.getElementById('canvas-preview')
var canvas = document.getElementById('canvas')
var takeIt = document.getElementById('takeIt')
var reClear = document.getElementById('reClear')
var upload = document.getElementById('upload')
var selectCamera = document.getElementById('selectCamera')
var videoList = []
getVideoList()
// 开启摄像头
function startCamera(cameraIndex) {
var video = document.getElementById('video')
var constraints = {
audio: false,
video: {
width: { ideal: 1280 },
height: { ideal: 960 },
deviceId: { exact: videoList[cameraIndex].deviceId }
}
}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
video.srcObject = stream
video.play()
// selectCamera.style.display = 'none'
takeIt.style.display = 'unset'
reClear.style.display = 'none'
upload.style.display = 'none'
}, function() {
alert('获取摄像头权限失败')
})
}
// 切换摄像头
function switchCamera() {
var selectedCamera = selectCamera.value
if (selectedCamera == "") {
return;
}
startCamera(parseInt(selectedCamera))
}
// 获取摄像头设备列表
function getVideoList() {
return new Promise((resolve, reject) => {
navigator.mediaDevices.enumerateDevices().then((devices) => {
const videoList = devices.filter(device => device.kind === 'videoinput')
resolve(videoList)
}).catch((err) => {
reject(err)
})
})
}
// 拍照、canvas绘制
function takePicture() {
var w = window.innerWidth - 50, h = window.innerHeight - 50
var video = document.getElementById('video')
var previewCnt = preview.getContext('2d')
var context = canvas.getContext('2d')
preview.style.display = 'block'
takeIt.style.display = 'none'
reClear.style.display = 'unset'
upload.style.display = 'unset'
previewCnt.drawImage(video, 0, 0, w, h)
context.drawImage(video, 0, 0, 1280, 960)
}
// 重拍
function reset() {
var w = window.innerWidth - 50, h = window.innerHeight - 50
var previewCnt = preview.getContext('2d')
var context = canvas.getContext('2d')
previewCnt.clearRect(0, 0, w, h)
context.clearRect(0, 0, 1280, 960)
preview.style.display = 'none'
takeIt.style.display = 'unset'
reClear.style.display = 'none'
upload.style.display = 'none'
}
// 上传图片
function uploadPhoto() {
var photo = window.location.href.split('?')[1]
var dataURL = canvas.toDataURL('image/jpeg')
eval(' window.opener.' + photo + '(dataURL)')
window.close()
}
// 获取摄像头列表
getVideoList().then((devices) => {
videoList = devices
if (videoList.length === 0) {
alert('没有检测到摄像头设备!')
return
}
selectCamera.style.display = 'unset'
for (var i = 0; i < videoList.length; i++) {
var option = document.createElement('option')
option.setAttribute('value', i)
option.innerText = videoList[i].label
selectCamera.appendChild(option)
}
}).catch((err) => {
alert('获取摄像头列表失败:' + err)
})
</script>
</html>