javascript - ImageCapture API 的替代方案以获得更好的浏览器支持
问题描述
我使用 OCR 来识别图像中的文本。我使用MediaStream中的ImageCapture API从用户的相机/视频输入中拍摄照片/快照。这是负责的代码:
function getBlobFromMediaStream() {
const videoTrack = mediaStream.getVideoTracks()[0]
const imageCapture = new ImageCapture(videoTrack);
return imageCapture.takePhoto().then(blob => {
if (!blob) throw "Photo could not be taken";
return blob;
})
}
太糟糕了,这个 API 在很多浏览器(Firefox、IE、Safari)上都不起作用。有没有可以使用的替代品?
解决方案
您可以使用 aHTMLVideoElement
和 a进行后备HTMLCanvasElement
。
首先通过检查窗口对象中是否存在构造函数来检查您的浏览器是否支持 MediaStream Image Capture API。
if ('ImageCapture' in window) {
// Has support for API.
} else {
// No support, use fallback.
}
然后基于此使用 API 或使用您的后备。
在后备中创建一个视频元素、画布元素和画布上下文。将 设置MediaStreamTrack
为srcObject
视频元素的。视频能够解码数据并制作实际图片。
使用视频的图像通过该方法将图像绘制到画布元素CanvasRenderingContext2D.drawImage()
。这样,canvas 元素将绘制视频中当前帧的图像。
现在您可以提取画布上绘制的数据并Blob
使用HTMLCanvasElement.toBlob()
方法将其转换为a。
将函数调用包装在 a 内有Promise
两个原因:
- 您需要从回调中提取 blob,Promise 包装器可以帮助您做到这一点。
- 该
ImageCapture.takePhoto()
方法还返回一个 Promise。因此,您将拥有与支持 API 时相同的行为。
所有放在一起它看起来像这样。
function getBlobFromMediaStream(stream) {
if ('ImageCapture' in window) {
const videoTrack = stream.getVideoTracks()[0];
const imageCapture = new ImageCapture(videoTrack);
return imageCapture.takePhoto();
} else {
const video = document.createElement('video');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
video.srcObject = stream;
return new Promise((resolve, reject) => {
video.addEventListener('loadeddata', async () => {
const { videoWidth, videoHeight } = video;
canvas.width = videoWidth;
canvas.height = videoHeight;
try {
await video.play();
context.drawImage(video, 0, 0, videoWidth, videoHeight);
canvas.toBlob(resolve, 'image/png');
} catch (error) {
reject(error);
}
});
});
}
}
如下例所示调用您的函数。我已经放弃了该throw
语句,以便在您调用该函数时在同一点捕获所有被拒绝的状态。getBlobFromMediaStream
根据 的文档ImageCapture.takePhoto()
,您要么Blob
在承诺履行时得到一个,要么在承诺被拒绝时得到一个错误。
后备也是如此。唯一的区别是,如果画布的位图不是原点干净的,则该HTMLCanvasElement.toBlob()
函数会抛出一个。SecurityError
getBlobFromMediaStream(mediaStream).then(blob => {
// Work with your blob.
}).catch(error => {
console.log(`Photo could not be taken. ${error}`);
})
推荐阅读
- asp.net - 从 ClaimsIdentity 获取 WindowsIdentity
- javascript - jQuery $.each() 不等待 $.Deferred()
- c++ - Qt 从主窗口打开对话框
- twitter-bootstrap - jstreetable 插件:宽度和上下文菜单的问题
- android - 在将没有签名页面的 apk 上传到时,测试凭据是否需要提供给 Google Play 以供查看
- r - 如何在一定时间后打破 R 中的循环?
- django - 自定义 Django 管理员
- java - 当我尝试将它放在我的 ImageView 前面时,TextView 消失了
- ubuntu - 安装 node js 时,命令 apt -get -f install 报错
- vue.js - Vue 监视字段仅从 UI 触发