当前位置: 首页 > news >正文

tag 网站备案成都网站建设方案外包

tag 网站备案,成都网站建设方案外包,wordpress主题pjax,肖港网站开发最近在做这个这项目奇店桶装水小程序V1.3.9安装包骑手端V2.0.1小程序前端 最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法…

最近在做这个这项目奇店桶装水小程序V1.3.9安装包+骑手端V2.0.1+小程序前端        

       最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法——使用Canvas来处理。

        这是真材实料的文章——让你的Canvas的技术更上一层楼!!!


效果图 


实现思路

1. 准备工作 视频和画布元素:在HTML模板中定义了一个<video>标签用于播放视频,以及一个<canvas>标签用来绘制处理后的视频帧。 初始化:在组件挂载(mounted)时,获取视频和画布元素,并初始化绘图上下文。

<template><div class="videoBgRemove"><!-- 视频元素 --><video ref="video" loop autoplay muted style="width: 240px;"><source src="/8_1736396574.mp4" type="video/mp4">Your browser does not support the video tag.</video><!-- 画布元素 --><canvas ref="canvas" width="200" height="450"></canvas></div>
</template><script>
export default {data() {return {featherStrength: 0.4, // 羽化强度控制};},mounted() {// 初始化视频和画布引用this.video = this.$refs.video;this.canvas = this.$refs.canvas;this.ctx = this.canvas.getContext('2d');this.canvas_tmp = document.createElement('canvas');this.canvas_tmp.width = this.canvas.width;this.canvas_tmp.height = this.canvas.height;this.ctx_tmp = this.canvas_tmp.getContext('2d');// 初始化其他变量this.init();},methods: {init() {// 当视频开始播放时,调用computeFrame进行逐帧处理this.video.addEventListener('play', this.computeFrame);}}
};
</script>

2. 视频帧处理逻辑 逐帧处理:当视频开始播放时,computeFrame函数会不断被调用,每次调用都会处理一帧视频数据。 临时画布:为了不影响原始视频的播放,所有图像处理都在一个临时创建的画布(canvas_tmp)上进行。 图像数据获取:从临时画布上获取当前帧的图像数据(像素信息)以进行处理。

methods: {computeFrame() {if (!this.video || this.video.paused || this.video.ended) return;// 绘制当前帧到临时画布上this.ctx_tmp.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);// 获取当前帧的图像数据let frame = this.ctx_tmp.getImageData(0, 0, this.canvas.width, this.canvas.height);// 后续处理...}
}

3. 背景移除 颜色检测:假设背景为特定的颜色(例如绿色),对于每个像素点,如果其RGB值符合预设的背景颜色范围,则将其alpha通道设置为0,即变为透明。

methods: {computeFrame() {// ... (前面的代码)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 < 100 && g > 120 && b < 200) { frame.data[i * 4 + 3] = 0; // 设置alpha通道为0,使背景透明}}// 后续处理...}
}

4. 羽化效果 边缘检测与平均:对于非透明的像素,计算它周围的像素,取周围像素颜色的平均值作为新颜色,并根据周围的透明度调整当前像素的透明度,以此来实现羽化效果。 强度控制:通过featherStrength参数可以控制羽化的程度,从而让边缘过渡更加自然。

methods: {computeFrame() {// ... (前面的代码)// 创建一个临时的数据副本,避免修改原始数据const tempData = [...frame.data];// 对非透明像素应用羽化效果for (let i = 0; i < pointLens; i++) {if (frame.data[i * 4 + 3] === 0) continue; // 忽略已经透明的像素// 计算当前像素的位置let [row, col] = this.numToPoint(i + 1, frame.width);// 获取周围的像素点let aroundPoints = this.getAroundPoint([row, col], frame.width, frame.height, 3);// 计算周围非透明像素的颜色平均值let opNum = 0;let rSum = 0;let gSum = 0;let bSum = 0;aroundPoints.forEach(([pRow, pCol]) => {let index = this.pointToNum([pRow, pCol], frame.width);rSum += tempData[(index - 1) * 4];gSum += tempData[(index - 1) * 4 + 1];bSum += tempData[(index - 1) * 4 + 2];if (tempData[(index - 1) * 4 + 3] !== 255) opNum++;});// 计算新的alpha值let alpha = (255 / aroundPoints.length) * (aroundPoints.length - opNum);// 根据羽化强度调整alphaif (alpha !== 255) {frame.data[i * 4] = parseInt(rSum / aroundPoints.length);frame.data[i * 4 + 1] = parseInt(gSum / aroundPoints.length);frame.data[i * 4 + 2] = parseInt(bSum / aroundPoints.length);frame.data[i * 4 + 3] = parseInt(alpha * this.featherStrength);}}// 将处理后的图像数据绘制到实际显示的画布上this.ctx.putImageData(frame, 0, 0);// 持续循环requestAnimationFrame(this.computeFrame);},numToPoint(num, width) {let col = num % width;let row = Math.floor(num / width);return [row + 1, col === 0 ? width : col];},pointToNum(point, width) {let [row, col] = point;return (row - 1) * width + col;},getAroundPoint(point, width, height, area) {let [row, col] = point;let allAround = [];for (let i = -Math.floor(area / 2); i <= Math.floor(area / 2); i++) {for (let j = -Math.floor(area / 2); j <= Math.floor(area / 2); j++) {if (i === 0 && j === 0) continue; // 跳过中心点let pRow = row + i;let pCol = col + j;if (pRow > 0 && pCol > 0 && pRow <= height && pCol <= width) {allAround.push([pRow, pCol]);}}}return allAround;}
}

5. 显示处理结果 更新画布:将处理后的图像数据应用到实际显示的画布(canvas)上,这样用户就能看到带有透明背景和羽化效果的视频了。

// 将处理后的图像数据绘制到实际显示的画布上
this.ctx.putImageData(frame, 0, 0);

6. 持续循环 递归调用:computeFrame函数会在每一帧处理完毕后立即再次调用自己,形成一个持续的循环,直到视频停止播放。代码加在这里面。

methods: {computeFrame() {// ... (前面的代码)// 持续循环requestAnimationFrame(this.computeFrame);}
}

完整的demo

1.App.vue

<template><div id="app"><h1>背景人像处理</h1><VideoRemoval /></div>
</template><script>
import VideoRemoval from './components/VideoRemoval.vue';export default {name: 'App',components: {VideoRemoval}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;background-image: url("../src/assets/web_bg.jpg"); /* 使用正确的路径 */background-size: cover; /* 背景图片覆盖整个容器 */background-position: center center; /* 背景图片居中显示 */background-repeat: no-repeat; /* 防止背景图片重复 */background-attachment: fixed; /* 背景固定在视口 */
}
</style>

2.VideoRemoval.vue

<template><div class="videoBgRemove"><video id="video"src="/8_1736396574.mp4"loopautoplaymutedref="video"style="width: 240px;"></video><canvas id="output-canvas"width="200"height="450"willReadFrequently="true"ref="canvas"></canvas></div>
</template><script>
export default {data () {return {video: null,canvas: null,ctx: null,canvas_tmp: null,ctx_tmp: null,featherStrength: 0.4, // 羽化强度控制};},methods: {init () {this.ctx = this.canvas.getContext('2d');this.canvas_tmp = document.createElement('canvas');this.canvas_tmp.setAttribute('width', 200);this.canvas_tmp.setAttribute('height', 450);this.ctx_tmp = this.canvas_tmp.getContext('2d');this.video.addEventListener('play', this.computeFrame);},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];},pointToNum (point, width) {let [row, col] = point;return (row - 1) * width + col;},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;});},computeFrame () {if (this.video) {if (this.video.paused || this.video.ended) return;}this.ctx_tmp.drawImage(this.video, 0, 0, this.video.clientWidth, this.video.clientHeight);let frame = this.ctx_tmp.getImageData(0, 0, this.video.clientWidth, this.video.clientHeight);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 < 100 && g > 120 && b < 200) {frame.data[i * 4 + 3] = 0;}}const tempData = [...frame.data];for (let i = 0; i < pointLens; i++) {if (frame.data[i * 4 + 3] === 0) continue;const currentPoint = this.numToPoint(i + 1, width);const arroundPoint = this.getAroundPoint(currentPoint, width, height, 3);let opNum = 0;let rSum = 0;let gSum = 0;let bSum = 0;arroundPoint.forEach((position) => {const index = this.pointToNum(position, width);rSum += tempData[(index - 1) * 4];gSum += tempData[(index - 1) * 4 + 1];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) {frame.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);// 根据羽化强度调整 alphaframe.data[i * 4 + 3] = parseInt(alpha * this.featherStrength);}}this.ctx.putImageData(frame, 0, 0);setTimeout(this.computeFrame, 0);}},mounted () {this.video = this.$refs.video;this.canvas = this.$refs.canvas;this.init();}
};
</script>

完整项目demo在前端给视频去除绿幕并替换背景: 最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法——使用Canvas来处理。         这是真材实料的文章——让你的Canvas的技术更上一层楼!!!


文章转载自:
http://story.tgcw.cn
http://ayah.tgcw.cn
http://scrambler.tgcw.cn
http://superexcellent.tgcw.cn
http://peyotl.tgcw.cn
http://lumumbist.tgcw.cn
http://localite.tgcw.cn
http://navalism.tgcw.cn
http://lipogrammatic.tgcw.cn
http://oarlock.tgcw.cn
http://stutteringly.tgcw.cn
http://familial.tgcw.cn
http://exobiology.tgcw.cn
http://chemical.tgcw.cn
http://concurrent.tgcw.cn
http://stentorian.tgcw.cn
http://lognormal.tgcw.cn
http://electrize.tgcw.cn
http://jibb.tgcw.cn
http://psychasthenia.tgcw.cn
http://woorali.tgcw.cn
http://wirily.tgcw.cn
http://brunt.tgcw.cn
http://disobedience.tgcw.cn
http://mollusc.tgcw.cn
http://plottage.tgcw.cn
http://euphausiid.tgcw.cn
http://lowlander.tgcw.cn
http://alastrim.tgcw.cn
http://robber.tgcw.cn
http://interfinger.tgcw.cn
http://loaiasis.tgcw.cn
http://corvus.tgcw.cn
http://intravasation.tgcw.cn
http://incipit.tgcw.cn
http://cardiosclerosis.tgcw.cn
http://syncategorematic.tgcw.cn
http://investigator.tgcw.cn
http://garbo.tgcw.cn
http://forcipiform.tgcw.cn
http://tally.tgcw.cn
http://nagoya.tgcw.cn
http://bedesman.tgcw.cn
http://moonfish.tgcw.cn
http://klunky.tgcw.cn
http://uropygium.tgcw.cn
http://molise.tgcw.cn
http://oligarchic.tgcw.cn
http://enlist.tgcw.cn
http://weighshaft.tgcw.cn
http://ethiopia.tgcw.cn
http://incommodity.tgcw.cn
http://trincomalee.tgcw.cn
http://trijugate.tgcw.cn
http://longshore.tgcw.cn
http://chapelgoer.tgcw.cn
http://effortless.tgcw.cn
http://scuttlebutt.tgcw.cn
http://cake.tgcw.cn
http://skatemobile.tgcw.cn
http://baroque.tgcw.cn
http://agamous.tgcw.cn
http://photodramatist.tgcw.cn
http://orthogenesis.tgcw.cn
http://tutoyer.tgcw.cn
http://rickettsial.tgcw.cn
http://coalpit.tgcw.cn
http://dipperful.tgcw.cn
http://sorb.tgcw.cn
http://declarant.tgcw.cn
http://chemiculture.tgcw.cn
http://aerogenically.tgcw.cn
http://otp.tgcw.cn
http://myna.tgcw.cn
http://downless.tgcw.cn
http://chipmuck.tgcw.cn
http://eda.tgcw.cn
http://gymnocarpous.tgcw.cn
http://rational.tgcw.cn
http://enteral.tgcw.cn
http://surveying.tgcw.cn
http://stonehearted.tgcw.cn
http://rapidly.tgcw.cn
http://puffbird.tgcw.cn
http://viscountcy.tgcw.cn
http://gentlewoman.tgcw.cn
http://chunnel.tgcw.cn
http://windjammer.tgcw.cn
http://tremellose.tgcw.cn
http://antibishop.tgcw.cn
http://preludize.tgcw.cn
http://milksop.tgcw.cn
http://amentiferous.tgcw.cn
http://zhengzhou.tgcw.cn
http://koza.tgcw.cn
http://henan.tgcw.cn
http://foretype.tgcw.cn
http://reedling.tgcw.cn
http://vicenza.tgcw.cn
http://emmarble.tgcw.cn
http://www.dt0577.cn/news/123125.html

相关文章:

  • 上海网站开发学校有哪些海外免费网站推广有哪些
  • 武汉做网站的公司有哪些搜索引擎营销的英文简称
  • 单位如何做网站宣传推广app用什么平台比较好
  • python做网站视频教程邯郸seo推广
  • 网站设计 中高端seo工具有哪些
  • 怎么做网站倒计时seo优化托管
  • 做图片推广的网站吗自己如何制作网站
  • 做背景图获取网站全网推广的方式
  • 网站建设需要哪些成本昆明优化网站公司
  • 近期的国际新闻重大事件seo排名点击首页
  • 澄海区建设局网站营销策划的十个步骤
  • 酷家乐软件下载电脑版seo全国最好的公司
  • 做印刷网站公司2000元代理微信朋友圈广告
  • 将自己做的网站发布到网上西安网站建设推广专家
  • 佛山网站建设外包公司百度云搜索引擎入口网盘搜索神器
  • 做文字头像的网站学生班级优化大师
  • 主题设计师站站长之家ip地址查询
  • 海珠网站建设报价企业网站制作要求
  • 专业建设指导委员会简述搜索引擎优化的方法
  • 周口公司做网站公关公司
  • 带数据的网站谷歌推广真有效果吗
  • 荣耀手机商城官方网站下载简短的营销软文范文
  • 搜索引擎wordpress网站优化+山东
  • 住房城市建设网站百度关键词价格查询
  • 武汉做网站冰洁找到冰洁工作室郑州seo外包阿亮
  • 买域名的网站网站可以自己做吗
  • 专业深圳网站建设公司深圳经济最新新闻
  • 电商网站 服务器成都百度网站排名优化
  • 长沙做网站zwnet沈阳网站关键词优化多少钱
  • wordpress企业商品展示模版杭州专业seo