使用 mask 实现视频弹幕人物遮罩过滤

简介: 使用 mask 实现视频弹幕人物遮罩过滤

经常看一些 LOL 比赛直播的小伙伴,肯定都知道,在一些弹幕网站(Bilibili、虎牙)中,当人物与弹幕出现在一起的时候,弹幕会“巧妙”的躲到人物的下面,看着非常的智能。


简单的一个截图例子:


cb1609fbe92444e38caa03d2dccef63b_tplv-k3u1fbpfcp-watermark.png


其实,这里是运用了 CSS 中的 MASK 属性实现的。


mask 简单用法介绍



之前在多篇文章都提到了 mask,比较详细的一篇是 -- 奇妙的 CSS MASK,本文不对 mask 的基本概念做过多讲解,向下阅读时,如果对一些 mask 的用法感到疑惑,可以再去看看。


这里只简单介绍下 mask 的基本用法:

最基本,使用 mask 的方式是借助图片,类似这样:


{
    /* Image values */
    mask: url(mask.png);                       /* 使用位图来做遮罩 */
    mask: url(masks.svg#star);                 /* 使用 SVG 图形中的形状来做遮罩 */
}

当然,使用图片的方式后文会再讲。借助图片的方式其实比较繁琐,因为我们首先还得准备相应的图片素材,除了图片,mask 还可以接受一个类似 background 的参数,也就是渐变。


类似如下使用方法:


{
    mask: linear-gradient(#000, transparent)                      /* 使用渐变来做遮罩 */
}

那该具体怎么使用呢?一个非常简单的例子,上述我们创造了一个从黑色到透明渐变色,我们将它运用到实际中,代码类似这样:


下面这样一张图片,叠加上一个从透明到黑色的渐变,


{
    background: url(image.png) ;
    mask: linear-gradient(90deg, transparent, #fff);
}

c49466c5f6e44835a36eb7fe178aa61e_tplv-k3u1fbpfcp-watermark.png


应用了 mask 之后,就会变成这样:


2e39b85d32c84a2987e9abd558d8c364_tplv-k3u1fbpfcp-watermark.png


这个 DEMO,可以先简单了解到 mask 的基本用法。


这里得到了使用 mask 最重要结论:添加了 mask 属性的元素,其内容会与 mask 表示的渐变的 transparent 的重叠部分,并且重叠部分将会变得透明。


值得注意的是,上面的渐变使用的是 linear-gradient(90deg, transparent, #fff),这里的 #fff 纯色部分其实换成任意颜色都可以,不影响效果。


CodePen Demo -- 使用 MASK 的基本使用


使用 mask 实现人物遮罩过滤



了解了 mask 的用法后,接下来,我们运用 mask,简单实现视频弹幕中,弹幕碰到人物,自动被隐藏过滤的例子。


首先,我简单的模拟了一个召唤师峡谷,以及一些基本的弹幕:


image.png


方便示意,这里使用了一张静态图,表示了召唤师峡谷的地图,并非真的视频,而弹幕则是一条一条的 <p> 元素,和实际情况一致。伪代码大概是这样:


<!-- 地图 -->
<div class="g-map"></div>
<!-- 包裹所有弹幕的容器 -->
<div class="g-barrage-container">
    <!-- 所有弹幕 -->
    <div class="g-barrage">6666</div>
    ...
    <div class="g-barrage">6666</div>
</div>


为了模拟实际情况,我们再用一个 div 添加一个实际的人物,如果不做任何处理,其实就是我们看视频打开弹幕的感受,人物被视频所遮挡:


image.png


注意,这里我添加了一个人物亚索,并且用 animation 模拟了简单的运动,在运动的过程中,人物是被弹幕给遮挡住的。

接下来,就可以请出 mask 了。

我们利用 mask 制作一个 radial-gradient ,使得人物附近为 transparent,并且根据人物运动的 animation,给 mask 的 mask-position 也添加上相同的 animation 即可。最终可以得到这样的效果:


.g-barrage-container {
    position: absolute;
    mask: radial-gradient(circle at 100px 100px, transparent 60px, #fff 80px, #fff 100%);
    animation: mask 10s infinite alternate;
}
@keyframes mask {
    100% {
        mask-position: 85vw 0;
    }
}


image.png

实际上就是给放置弹幕的容器,添加一个 mask 属性,把人物所在的位置标识出来,并且根据人物的运动不断的去变换这个 mask 即可。我们把 mask 换成 background,原理一看就懂。


把 mask 替换成 background 示意图:


2418bbd6f3d449d7bfddd4fd93da53e0_tplv-k3u1fbpfcp-watermark.gif




background 透明的地方,即 mask 中为 transparent 的部分,实际就是弹幕会被隐藏遮罩的部分,而其他白色部分,弹幕不会被隐藏,正是完美的利用了 mask 的特性。


其实这项技术和视频本身是无关的,我们只需要根据视频计算需要屏蔽掉弹幕的位置,得到相应的 mask 参数即可。如果去掉背景和运动的人物,只保留弹幕和 mask,是这样的:


663a15a6087f4a12b8c57b3f0efca80f_tplv-k3u1fbpfcp-watermark.gif


要明确的是,使用 mask,不是将弹幕部分给遮挡住,而是利用 mask,指定弹幕容器之下,哪些部分正常展示,哪些部分透明隐藏。


最后,完整的 Demo 你可以戳这里:


CodePen Demo -- mask 实现弹幕人物遮罩过滤


实际生产环境中的运用



当然,上面我们简单的还原了利用 mask 实现弹幕遮罩过滤的效果。但是实际情况比上述的场景复杂的多,因为人物英雄的位置是不确定的,每一刻都在变化。所以在实际生产环境中,mask 图片的参数,其实是由后端实时对视频进行处理计算出来的,然后传给前端,前端再进行渲染。


对于运用了这项技术的直播网站,我们可以审查元素,看到包裹弹幕的容器的 mask 属性,每时每刻都在发生变化:

a26980af15d04dcfabe058fe70a95816_tplv-k3u1fbpfcp-watermark.gif

返回回来的其实是一个 SVG 图片,大概长这个样子:


image.png



这样,根据视频人物的实时位置变化,不断计算新的 mask,再实时作用于弹幕容器之上,实现遮罩过滤。

目录
相关文章
|
Linux
【PyAutoGUI操作指南】05 屏幕截图与图像定位:截图+定位单个目标+定位全部目标+灰度匹配+像素匹配+获取屏幕截图中像素的RGB颜色
【PyAutoGUI操作指南】05 屏幕截图与图像定位:截图+定位单个目标+定位全部目标+灰度匹配+像素匹配+获取屏幕截图中像素的RGB颜色
1056 0
|
1月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
53 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
4月前
|
JavaScript
文本,视频网站轮播框如何只播放前五条数据
文本,视频网站轮播框如何只播放前五条数据
|
6月前
|
传感器 人工智能 搜索推荐
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
103 0
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
|
6月前
|
C++
[Halcon&定位] 解决Roi区域外的模板匹配成功
[Halcon&定位] 解决Roi区域外的模板匹配成功
207 0
|
编解码
使用遮罩提取图像中感兴趣的区域
使用遮罩隔离感兴趣区域 (ROI) 来有效地处理被阻止的图像。 某些大图像源仅在图像的一小部分中具有有意义的数据。可以通过将处理限制为包含有意义数据的 ROI 来缩短总处理时间。使用掩码定义投资回报率。蒙版是一种逻辑图像,其中像素表示投资回报率。
127 1
|
人工智能 自然语言处理 前端开发
效果:mask-image 哔哩哔哩弹幕不遮挡人物
效果:mask-image 哔哩哔哩弹幕不遮挡人物
168 0
效果:mask-image 哔哩哔哩弹幕不遮挡人物
|
人工智能 数据可视化 测试技术
卷!用扩散模型合成连贯视觉故事,输入字幕就能脑补画面,代词ta都分得清
卷!用扩散模型合成连贯视觉故事,输入字幕就能脑补画面,代词ta都分得清
170 0
|
机器学习/深度学习 编解码 计算机视觉
两张照片就能转视频!Google提出FLIM帧插值模型
两张照片就能转视频!Google提出FLIM帧插值模型
219 0