中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

做個(gè)網(wǎng)站 多少錢網(wǎng)絡(luò)新聞發(fā)布平臺

做個(gè)網(wǎng)站 多少錢,網(wǎng)絡(luò)新聞發(fā)布平臺,免費(fèi)網(wǎng)站在線觀看,如何用七牛云做視頻網(wǎng)站Js去除視頻背景 注: 這里的去除視頻背景并不是對視頻文件進(jìn)行操作去除背景 如果需要對視頻扣除背景并導(dǎo)出可以使用ffmpeg等庫,這里僅作播放用所以采用這種方法 由于uniapp中的canvas經(jīng)過封裝,且 uniapp 的 drawImage 無法繪制視頻幀畫面&…

Js去除視頻背景


注: 這里的去除視頻背景并不是對視頻文件進(jìn)行操作去除背景

如果需要對視頻扣除背景并導(dǎo)出可以使用ffmpeg等庫,這里僅作播放用所以采用這種方法

由于uniapp中的canvas經(jīng)過封裝,且 uniapp 的 drawImage 無法繪制視頻幀畫面,因此uniapp中不適用


實(shí)現(xiàn)過程是將視頻使用canvas逐幀截下來對截取的圖片進(jìn)行處理,然后在canvas中顯示處理好的圖片

最后通過定時(shí)器高速處理替換,形成視頻播放的效果,效果如下圖?

在這里插入圖片描述

邊緣仍然會有些綠幕的像素,可以通過其他的處理進(jìn)行優(yōu)化


原理

首先使用canvas的 drawImage 方法將video的當(dāng)前幀畫面繪制到canvas中

然后再通過 getImageData 方法獲取當(dāng)前canvas的所有像素的rgba值組成的數(shù)組

獲取到的值為[r,g,b,a,r,g,b,a,...],每一組rgba的值就是一個(gè)像素,所以獲取到的數(shù)組長度是canvas的像素的數(shù)量 * 4

通過判斷每一組rgb的值是否為綠幕像素,然后設(shè)置其透明通道的alpha的值為0實(shí)現(xiàn)效果


代碼

因?yàn)閏anvas會受到跨域的影響導(dǎo)致畫布被污染,因此首先需要將測試視頻下載到本地

如果直接本地打開html的話同樣會因?yàn)楸镜芈窂綀?bào)跨域錯(cuò)誤,需要將html,js,測試視頻放在文件夾中部署一個(gè)本地服務(wù)器

可以使用http-server

npm i http-server -g# 切換到存放html,js,測試視頻的文件夾 運(yùn)行命令即可部署本地服務(wù)器http-server

或者

vsCode的Live server插件均可

測試視頻 地址

<!DOCTYPE html>
<html lang="en"><head><style>video{width: 480px;height: 270px;}</style></head><body><video id="video"  src="./63e1dd7ddd2b0.mp4"  loop autoplay muted></video><canvas id="output-canvas" width="480" height="270" willReadFrequently="true"></canvas><script type="text/javascript" src="processor2.js"></script></body>
</html>
// processor2.jslet video, canvas, ctx, canvas_tmp, ctx_tmp;function init () {video = document.getElementById('video');canvas = document.getElementById('output-canvas');ctx = canvas.getContext('2d');// 創(chuàng)建的canvas寬高最好與顯示圖片的canvas、video寬高一致canvas_tmp = document.createElement('canvas');canvas_tmp.setAttribute('width', 480);canvas_tmp.setAttribute('height', 270);ctx_tmp = canvas_tmp.getContext('2d');video.addEventListener('play', computeFrame);
}function computeFrame () {if (video) {if (video.paused || video.ended) return;}// 如果視頻比例和canvas比例不正確可能會出現(xiàn)顯示形變, 調(diào)整除的值進(jìn)行比例調(diào)整ctx_tmp.drawImage(video, 0, 0, video.clientWidth / 1, video.clientHeight / 1);// 獲取到繪制的canvas的所有像素rgba值組成的數(shù)組let frame = ctx_tmp.getImageData(0, 0, video.clientWidth, video.clientHeight);// 共有多少像素點(diǎn)const pointLens = frame.data.length / 4;for (let i = 0; i < pointLens; i++) {let r = frame.data[i * 4];let g = frame.data[i * 4 + 1];let b = frame.data[i * 4 + 2];// 判斷如果rgb值在這個(gè)范圍內(nèi)則是綠幕背景,設(shè)置alpha值為0 // 同理不同顏色的背景調(diào)整rgb的判斷范圍即可if (r < 100 && g > 120 && b < 200) {frame.data[i * 4 + 3] = 0;}}// 重新繪制到canvas中顯示ctx.putImageData(frame, 0, 0);// 遞歸調(diào)用setTimeout(computeFrame, 0);
}document.addEventListener("DOMContentLoaded", () => {init();
});

使用本地服務(wù)器訪問html即可看到效果,可以看到邊緣仍有綠色像素閃爍

一般情況這種就可以了,使用算法進(jìn)行處理的話效果會更好,但相應(yīng)的資源的消耗也會提升,造成幀率下降

下面展示通過一些算法進(jìn)行羽化和顏色過渡

羽化

// 返回canvas中第num個(gè)像素點(diǎn)所在的坐標(biāo)  12 -> [1, 12]
function numToPoint (num, width) {let col = num % width;let row = Math.floor(num / width);row = col === 0 ? row : row + 1;col = col === 0 ? width : col;return [row, col];
}// 返回canvas中所在坐標(biāo)的num(index + 1)值  [1, 12] -> 12
function pointToNum (point, width) {let [row, col] = point;return (row - 1) * width + col
}// 獲取輸入的坐標(biāo)周圍1像素內(nèi)的所有像素的坐標(biāo)組成的數(shù)組 [1, 1] -> [[1, 2], [2, 1], [2, 2]]
function getAroundPoint (point, width, height, area) {let [row, col] = point;let allAround = [];if (row > height || col > width || row < 0 || col < 0) return allAround;for (let i = 0; i < area; i++) {let pRow = row - 1 + i;for (let j = 0; j < area; j++) {let pCol = col - 1 + j;if (i === area % 2 && j === area % 2) continue;allAround.push([pRow, pCol]);}}return allAround.filter(([iRow, iCol]) => {return (iRow > 0 && iCol > 0) && (iRow <= height && iCol <= width);})
}

通過上面的函數(shù)獲取到一個(gè)選定的不透明的像素周圍的像素后,判斷周圍的像素的alpha值

如果周圍的像素有存在透明的像素,則重新計(jì)算選定像素的alpha值


顏色過渡

計(jì)算修改alpha值連帶計(jì)算周圍像素中rgb的各項(xiàng)平均值給選定像素

最終處理結(jié)果如下
在這里插入圖片描述


代碼

// 新增羽化和顏色過渡// processor2.js
let video, canvas, ctx, canvas_tmp, ctx_tmp;function init () {video = document.getElementById('video');canvas = document.getElementById('output-canvas');ctx = canvas.getContext('2d');// 創(chuàng)建的canvas寬高最好與顯示圖片的canvas、video寬高一致canvas_tmp = document.createElement('canvas');canvas_tmp.setAttribute('width', 480);canvas_tmp.setAttribute('height', 270);ctx_tmp = canvas_tmp.getContext('2d');video.addEventListener('play', computeFrame);
}function numToPoint (num, width) {let col = num % width;let row = Math.floor(num / width);row = col === 0 ? row : row + 1;col = col === 0 ? width : col;return [row, col];
}function pointToNum (point, width) {let [row, col] = point;return (row - 1) * width + col
}function getAroundPoint (point, width, height, area) {let [row, col] = point;let allAround = [];if (row > height || col > width || row < 0 || col < 0) return allAround;for (let i = 0; i < area; i++) {let pRow = row - 1 + i;for (let j = 0; j < area; j++) {let pCol = col - 1 + j;if (i === area % 2 && j === area % 2) continue;allAround.push([pRow, pCol]);}}return allAround.filter(([iRow, iCol]) => {return (iRow > 0 && iCol > 0) && (iRow <= height && iCol <= width);})
}function computeFrame () {if (video) {if (video.paused || video.ended) return;}ctx_tmp.drawImage(video, 0, 0, video.clientWidth, video.clientHeight);let frame = ctx_tmp.getImageData(0, 0, video.clientWidth, video.clientHeight);//----- emergence ----------const height = frame.height;const width = frame.width;const pointLens = frame.data.length / 4;for (let i = 0; i < pointLens; i++) {let r = frame.data[i * 4];let g = frame.data[i * 4 + 1];let b = frame.data[i * 4 + 2];if (r < 150 && g > 200 && b < 150) {frame.data[i * 4 + 3] = 0;}}const tempData = [...frame.data]for (let i = 0; i < pointLens; i++) {if (frame.data[i * 4 + 3] === 0) continueconst currentPoint = numToPoint(i + 1, width);const arroundPoint = getAroundPoint(currentPoint, width, height, 3);let opNum = 0;let rSum = 0;let gSum = 0;let bSum = 0;arroundPoint.forEach((position) => {const index = pointToNum(position, width);rSum = rSum + tempData[(index - 1) * 4];gSum = gSum + tempData[(index - 1) * 4 + 1];bSum = bSum + tempData[(index - 1) * 4 + 2];if (tempData[(index - 1) * 4 + 3] !== 255) opNum++;})let alpha = (255 / arroundPoint.length) * (arroundPoint.length - opNum);if (alpha !== 255) {// debuggerframe.data[i * 4] = parseInt(rSum / arroundPoint.length);frame.data[i * 4 + 1] = parseInt(gSum / arroundPoint.length);frame.data[i * 4 + 2] = parseInt(bSum / arroundPoint.length);frame.data[i * 4 + 3] = parseInt(alpha);}}//------------------------ctx.putImageData(frame, 0, 0);setTimeout(computeFrame, 0);
}document.addEventListener("DOMContentLoaded", () => {init();
});
http://www.risenshineclean.com/news/57020.html

相關(guān)文章:

  • 專業(yè)建設(shè)企業(yè)網(wǎng)站免費(fèi)做網(wǎng)站的平臺
  • 正規(guī)網(wǎng)站開發(fā)公司seo公司排名教程
  • 制作購物網(wǎng)站怎么做seo網(wǎng)站關(guān)鍵詞優(yōu)化
  • dns設(shè)置 看國外網(wǎng)站百度應(yīng)用下載
  • 網(wǎng)站制作百度網(wǎng)盤網(wǎng)絡(luò)推廣比較經(jīng)典和常用的方法有
  • wordpress tdk鄭州seo排名扣費(fèi)
  • 彩票自己開盤做網(wǎng)站多地優(yōu)化完善疫情防控措施
  • 哪些網(wǎng)站可以做招商廣告持啊傳媒企業(yè)推廣
  • wordpress更改路徑湖北網(wǎng)站seo設(shè)計(jì)
  • 中國新聞社是央企嗎成都seo
  • 做網(wǎng)站可以申請國家補(bǔ)助嗎西安網(wǎng)站制作建設(shè)
  • 哪些網(wǎng)站是react做的企業(yè)培訓(xùn)師資格證報(bào)考2022
  • 山東泰安最新疫情深圳搜狗seo
  • 網(wǎng)站建設(shè)報(bào)名系統(tǒng)是真的嗎蘇州seo快速優(yōu)化
  • 杭州哪里做網(wǎng)站好如何快速推廣網(wǎng)上國網(wǎng)
  • 1.網(wǎng)站建設(shè)基本流程是什么關(guān)鍵詞排名優(yōu)化技巧
  • 網(wǎng)站專題頁面設(shè)計(jì)欣賞網(wǎng)絡(luò)營銷是指
  • 企業(yè)信用網(wǎng)站建設(shè)網(wǎng)絡(luò)運(yùn)營培訓(xùn)哪里有學(xué)校
  • 微企免費(fèi)網(wǎng)站建設(shè)制作網(wǎng)站要花多少錢
  • 班級網(wǎng)站源代碼下載關(guān)鍵詞查網(wǎng)址
  • thinkphp開發(fā)企業(yè)網(wǎng)站廣州seo網(wǎng)站推廣優(yōu)化
  • 做網(wǎng)站容易找工作嗎互聯(lián)網(wǎng)推廣有哪些方式
  • 怎么建設(shè)企業(yè)網(wǎng)站網(wǎng)絡(luò)推廣營銷
  • 濟(jì)南集團(tuán)網(wǎng)站建設(shè)公司河南推廣網(wǎng)站
  • 做網(wǎng)站有2個(gè)前提條件 一個(gè)是網(wǎng)站如何做百度免費(fèi)推廣
  • 開發(fā)安卓app關(guān)鍵詞優(yōu)化的發(fā)展趨勢
  • wordpress移動友好度大揭秘搜索引擎優(yōu)化seo的英文全稱是
  • 網(wǎng)站建設(shè)是不是無形資產(chǎn)深圳債務(wù)優(yōu)化公司
  • 新聞發(fā)布網(wǎng)站如果做初學(xué)seo網(wǎng)站推廣需要怎么做
  • wordpress手機(jī)網(wǎng)站怎么做3天網(wǎng)站seo優(yōu)化成為超級品牌