日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
Electron應用中實現(xiàn)調用外接攝像頭并拍照上傳

背景

基于Electron實現(xiàn)的pc端智能驗機應用,近期迭代了一個新的功能,需求是通過電腦外接攝像頭對手機屏幕進行拍照,拍照后需將照片上傳至服務端進行屏幕信息比對,確定被檢測屏幕是否為原廠屏。

成都創(chuàng)新互聯(lián)公司專注于企業(yè)全網整合營銷推廣、網站重做改版、鳳陽網站定制設計、自適應品牌網站建設、H5網站設計、商城網站制作、集團公司官網建設、外貿營銷網站建設、高端網站制作、響應式網頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為鳳陽等各大城市提供網站開發(fā)制作服務。

需求分析

根據上面的需求,分析大概要以下幾個步驟。

  1. 先實現(xiàn)將攝像頭的畫面實時展示在頁面視頻采集區(qū)域中;
  2. 將攝像頭中的視頻畫面采集一幀成圖片并回顯;
  3. 將生成的圖片上傳至CDN拿到圖片鏈接;
  4. 將圖片鏈接上傳到后端接口做處理;

確定了需要以上四個步驟后,接下來一步一步實現(xiàn)。

實現(xiàn)

視頻采集

由于 Electron 內置了 Chromium 瀏覽器,該瀏覽器對各項前端標準都支持得非常好,所以基于 Electron 開發(fā)應用不會遇到瀏覽器兼容性問題。幾乎可以在 Electron 中使用所有 HTML5、CSS3 、ES6 標準中定義的 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 對象。若找不到滿足請求參數(shù)的媒體類型,promise會reject回調一個NotFoundError。

現(xiàn)在已經成功獲取到視頻流,接下來就是將視頻流回顯到頁面。這里使用video標簽完成,代碼如下:



export default {
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)
})

得到的設備列表數(shù)據格式如下:

kind類型有三種,分別是audioinput、audiooutput和videoinput。分別代表音視頻的輸入和輸出。可在列表中查找目標媒體是否已經接入且可用。

若有選擇切換設備需求,可根據kind類型進行媒體設備分類,選擇目標deviceId,傳入navigator.mediaDevices.getUserMedia,完成來源切換。

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

拍照生成圖片

拍照其實就是截取視頻中的某一幀,這里使用canvas來實現(xiàn)截取。getContext() 方法可返回一個對象,該對象提供了用于在畫布上繪圖的方法和屬性。其中drawImage()方法用來向畫布上繪制圖像、畫布或視頻。



export default {
data: {
showVideo: true, // 是否展示攝像頭畫面
},
methods: {
/* 拍照按鈕點擊 */
capture() {
this.showVideo = false
var context = this.$refs.canvas.getContext('2d');
/* 要跟video的寬高一致 */
context.drawImage(this.$refs.video, 0, 0, 1000, 692, 0, 0, 500, 346);
}
}
}

拍照的圖片回顯至canvas標簽。

上傳圖片至CDN

上個步驟已經完成了拍照,接下來就需要將圖片上傳至CDN,拿到圖片鏈接。這里有兩種方式可以實現(xiàn)獲取圖片數(shù)據。

1. 使用HTMLCanvasElement.toBlob()

HTMLCanvasElement.toBlob() 方法生成 Blob 對象,用以展示 canvas 上的圖片。因為直接可以拿到圖片文件,所以無需再使用方法2中的函數(shù)來轉化base64,直接可以獲取到圖片文件用來上傳。

語法
toBlob(callback, type, quality)
參數(shù)

callback:回調函數(shù),參數(shù)為Blob對象(目標圖片文件)。

type:圖片格式,默認為image/png 可選。

quality:0-1的數(shù)字,表示圖片質量,可選。

點擊提交按鈕按鈕時,先獲取圖片文件,為上傳做準備。

methods: {
/* 提交按鈕點擊 */
submit() {
const base64Url = this.$refs.canvas.toBlob(blob => {
console.log('===blob', blob)
const data = new FormData()
data.append('file', blob)
request.post('https://XXXXX/upload', data)
}, "image/jpeg", 0.95)
}
}

console的結果如下圖:

2. 使用HTMLCanvasElement.toDataURL()

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

Data URL,即前綴為 data: 協(xié)議的 URL,其允許內容創(chuàng)建者向文檔中嵌入小文件。

語法

canvas.toDataURL(type, encoderOptions);

參數(shù)

type 圖片格式,默認為image/png。

encoderOptions 0到1之間的值,用來選定圖片質量,默認值是0.92,超出范圍會使用默認值。

返回值

base64組成的圖片源數(shù)據,上傳前需轉為圖片文件。這里封裝了一個convertBase64UrlToImgFile函數(shù)用來轉換。代碼如下:



export default {
data: {
/* 是否展示攝像頭畫面 */
showVideo: true,
},
methods: {
/* 將base64轉為圖片文件 */
convertBase64UrlToImgFile(urlData, fileType) {
const imgData = urlData.split('base64,').splice(-1)[0]
/* 解碼使用 base-64 編碼的字符串 轉換為byte */
const bytes = window.atob(imgData)

/* 處理異常,將ASCII碼小于0的轉換為大于0 */
const ab = new ArrayBuffer(bytes.length)
const ia = new Int8Array(ab)

for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}

/* 轉換成文件,可以添加文件的type,lastModifiedDate屬性 */
const blob = new Blob([ab], { type: fileType })
blob.lastModifiedDate = new Date()
return blob
},
/* 提交按鈕點擊 */
async submit() {
const base64Url = this.$refs.canvas.toDataURL()
const imgFile = this.convertBase64UrlToImgFile(base64Url, 'image/jpg')
console.log('====imgFile', imgFile)
const data = new FormData()
data.append('file', imgFile)
/* 上傳 */
request.post('https://XXXXX/upload', data)
},
}
}

convertBase64UrlToImgFile可用于在使用canvas外的場景進行base64轉換圖片文件。和HTMLCanvasElement.toBlob()方法得到的結果一致。

以上兩種方法都可以完成圖片上傳,最終拿到CDN圖片鏈接后可傳給后端進行處理。獲取屏幕信息。

總結

通過以上四個步驟就完成了Electron應用中通過外接攝像頭拍照并上傳的功能。這里基本用不到Electron的能力,和在web端的實現(xiàn)方式并無區(qū)別,Electron在這里起到的作用就是獲取攝像頭媒體流不需要獲取用戶權限。

Electron是基于Chromium和Node.js實現(xiàn)的,這就使前端開發(fā)者可以使用JavaScript、HTML和CSS輕松構建跨平臺的桌面應用。Electron可以使用幾乎所有的Web前端生態(tài)領域及Node.js生態(tài)領域的組件和技術方案。


當前題目:Electron應用中實現(xiàn)調用外接攝像頭并拍照上傳
標題鏈接:http://www.5511xx.com/article/coeisgi.html