Electron怎么实现调用外接摄像头并拍照上传(electron,开发技术)

时间:2024-04-29 08:03:29 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

    背景

    基于Electron实现的pc端智能验机应用,近期迭代了一个新的功能,需求是通过电脑外接摄像头对手机屏幕进行拍照,拍照后需将照片上传至服务端进行屏幕信息比对,确定被检测屏幕是否为原厂屏。

    需求分析

    根据上面的需求,分析大概要以下几个步骤。

    • 先实现将摄像头的画面实时展示在页面视频采集区域中;

    • 将摄像头中的视频画面采集一帧成图片并回显;

    • 将生成的图片上传至CDN拿到图片链接;

    • 将图片链接上传到后端接口 做处理;

    确定了需要以上四个步骤后,接下来一步一步实现。

    实现

    视频采集

    由于 Electron 内置了 Chromium 浏览器,该浏览器对各项前端标准都支持得非常好,所以基于 Electron 开发应用不会遇到浏览器兼容性问题。几乎可以在 Electron 中使用所有 HTML5CSS3ES6 标准中定义的 API

    所以基于WebRTC提供的API即可获取到摄像头的视频流。

    MediaDevices.getUserMedia()

    代码如下:

    methods:{getUserMedia(){/*可同时开启video(摄像头)和audio(麦克风)这里只请求摄像头,所以只设置video为true*/navigator.mediaDevices.getUserMedia({video:true}).then(function(stream){/*使用这个stream传递到成功回调中*/this.success(stream)}).catch(function(err){/*处理error信息*/this.error(error)});}}

    MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其它轨道类型。

    它返回一个 Promise 对象,成功后会resolve回调一个 MediaStream 对象。若找不到满足请求参数的媒体类型,promisereject回调一个NotFoundError

    现在已经成功获取到视频流,接下来就是将视频流回显到页面。 这里使用video标签完成,代码如下:

    <template><divclass="video-page"><divclass="video-content"><videoref="video"class="video-item"></video></div></div></template>exportdefault{methods:{getUserMedia(){/*可同时开启video(摄像头)和audio(麦克风)这里只请求摄像头,所以只设置video为true*/navigator.mediaDevices.getUserMedia({video:true}).then(function(stream){/*使用这个stream传递到成功回调中*/this.success(stream)}).catch(function(err){/*处理error信息*/this.error(error)});},success(stream){console.log('成功',stream);/*将stream分配给video标签*/this.$refs.video.srcObject=stream;this.$refs.video.play();}}}

    这时,摄像头中的画面就可以显示在页面video标签内。

    为了用户体验,在进入页面之前添加了判断摄像头是否已经接入并可用的逻辑,避免用户的摄像头未接入或者启动,造成应用不可用的错觉。

    使用MediaDevices.enumerateDevices()来获取可用媒体输入和输出设备的列表,例如摄像头、麦克风、耳机等。

    navigator.mediaDevices.enumerateDevices().then(devicesList=>{console.log('------devicesList',deviceList)})

    得到的设备列表数据格式如下:

    Electron怎么实现调用外接摄像头并拍照上传

    kind类型有三种,分别是audioinputaudiooutputvideoinput。分别代表音视频的输入和输出。可在列表中查找目标媒体是否已经接入且可用。

    若有选择切换设备需求,可根据kind类型进行媒体设备分类,选择目标deviceId,传入navigator.mediaDevices.getUserMedia,完成来源切换。

    navigator.mediaDevices.getUserMedia({video:{deviceId:xxxx}})

    拍照生成图片

    拍照其实就是截取视频中的某一帧,这里使用canvas来实现截取。getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。其中drawImage()方法用来向画布上绘制图像、画布或视频。

    <template><divclass="video-page"><divclass="video-content"><videoref="video"class="video-item"v-if="showVideo"></video><canvasref="canvas"v-elsewidth="500"height="346"></canvas><divclass="video-buttons"><div@click="capture"class="button-itemcapture">拍照</div><div@click="submit"class="button-itemsubmit"}">提交</div></div></div></template>exportdefault{data:{showVideo:true,//是否展示摄像头画面},methods:{/*拍照按钮点击*/capture(){this.showVideo=falsevarcontext=this.$refs.canvas.getContext('2d');/*要跟video的宽高一致*/context.drawImage(this.$refs.video,0,0,1000,692,0,0,500,346);}}}

    拍照的图片回显至canvas标签。

    上传图片至CDN

    上个步骤已经完成了拍照,接下来就需要将图片上传至CDN,拿到图片链接。 这里有两种方式可以实现获取图片数据。

    1. 使用HTMLCanvasElement.toBlob()

    HTMLCanvasElement.toBlob() 方法生成 Blob 对象,用以展示 canvas 上的图片。因为直接可以拿到图片文件,所以无需再使用方法2中的函数来转化base64,直接可以获取到图片文件用来上传。

    语法

    toBlob(callback,type,quality)

    参数

    callback:回调函数,参数为Blob对象(目标图片文件)。

    type:图片格式,默认为image/png 可选

    quality:0-1的数字,表示图片质量,可选

    点击提交按钮按钮时,先获取图片文件,为上传做准备。

    methods:{/*提交按钮点击*/submit(){constbase64Url=this.$refs.canvas.toBlob(blob=>{console.log('===blob',blob)constdata=newFormData()data.append('file',blob)request.post('https://XXXXX/upload',data)},"image/jpeg",0.95)}}

    console的结果如下图:

    Electron怎么实现调用外接摄像头并拍照上传

    2. 使用HTMLCanvasElement.toDataURL()

    HTMLCanvasElement.toDataURL()方法返回一个包含图片展示的Data URL。

    Data URL,即前缀为 data: 协议的 URL,其允许内容创建者向文档中嵌入小文件。

    语法
    canvas.toDataURL(type,encoderOptions);
    参数

    type 图片格式,默认为image/png

    encoderOptions 0到1之间的值,用来选定图片质量,默认值是0.92,超出范围会使用默认值。

    返回值

    base64组成的图片源数据,上传前需转为图片文件。这里封装了一个convertBase64UrlToImgFile函数用来转换。代码如下:

    <template><divclass="video-page"><divclass="video-content"><videoref="video"class="video-item"v-if="showVideo"></video><canvasref="canvas"v-elsewidth="500"height="346"></canvas><divclass="video-buttons"><div@click="capture"class="button-itemcapture">拍照</div><div@click="submit"class="button-itemsubmit">提交</div></div></div></template>exportdefault{data:{/*是否展示摄像头画面*/showVideo:true,},methods:{/*将base64转为图片文件*/convertBase64UrlToImgFile(urlData,fileType){constimgData=urlData.split('base64,').splice(-1)[0]/*解码使用base-64编码的字符串转换为byte*/constbytes=window.atob(imgData)/*处理异常,将ASCII码小于0的转换为大于0*/constab=newArrayBuffer(bytes.length)constia=newInt8Array(ab)for(leti=0;i<bytes.length;i++){ia[i]=bytes.charCodeAt(i)}/*转换成文件,可以添加文件的type,lastModifiedDate属性*/constblob=newBlob([ab],{type:fileType})blob.lastModifiedDate=newDate()returnblob},/*提交按钮点击*/asyncsubmit(){constbase64Url=this.$refs.canvas.toDataURL()constimgFile=this.convertBase64UrlToImgFile(base64Url,'image/jpg')console.log('====imgFile',imgFile)constdata=newFormData()data.append('file',imgFile)/*上传*/request.post('https://XXXXX/upload',data)},}}

    convertBase64UrlToImgFile可用于在使用canvas外的场景进行base64转换图片文件。和HTMLCanvasElement.toBlob()方法得到的结果一致。

    以上两种方法都可以完成图片上传,最终拿到CDN图片链接后可传给后端进行处理。获取屏幕信息。

     </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
    本文:Electron怎么实现调用外接摄像头并拍照上传的详细内容,希望对您有所帮助,信息来源于网络。
    上一篇:dm.jdbc.driver.DMException网络通信异常如何解决下一篇:

    8 人围观 / 0 条评论 ↓快速评论↓

    (必须)

    (必须,保密)

    阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18