我正在努力实现目前可能在效果之后的效果,效果是关于剪辑屏幕(luma matte)一个视频与另一个视频,所以最终的输出将是一个透明的视频。但我正在尝试制作动态透明的HTML内容。
视频看起来像这样:https://www.youtube.com/watch?v=jfzcrO4694E
基本上通过改变透明度来揭示HTML内容。
这必须是关于+的东西,但是在谷歌搜索大约一个小时后,找不到任何可以改变HTML内容透明度的黑白影片的描述和效果。
有什么想法吗?
答案 0 :(得分:3)
HTML5不支持alpha通道视频(例如MOV 32位等)。
唯一的选择是使用matte合成,就像你的视频结合了canvas元素一样。但是,canvas仅复合已存在的Alpha通道,并且作为matte是固体图层而不是alpha,您必须将其转换为alpha。
这意味着您必须绘制每个帧并将其迭代到画布,并将灰度转换为透明度级别。但是,这非常占用CPU,会影响计算机性能/资源。视频还必须满足CORS要求,以免污染画布(在这种情况下,您无法提取像素)。
对于每一帧:
示例循环(假设视频是动态创建的,设置了源代码并触发了启动事件 - 画布放置在您要屏蔽的位置,并初始化上下文ctx
):
ctx.globalCompositeOperation = "copy"; // will clear previous alpha
function unmask() {
ctx.drawImage(video, 0, 0); // draw current video frame
var idata = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height),
data = idata.data,
len = data.length, i = 0; // ..image data from canvas
while(i < len) {
var alpha = 255 - data[i]; // in this matte, white = fully transparent
data[i] = data[i+1] = data[i+2] = 0; // clear matte to black
data[i+3] = alpha; // set alpha
i += 4; // next pixel
}
ctx.putImageData(idata, 0, 0); // update canvas
requestAnimationFrame(unmask); // todo: add criteria to stop this
}
加速提示:使用黑色(或预先反转遮罩视频),然后对数据使用Uint32Array视图,右移一个像素长字(&lt;&lt; 24)到位。
您可以使用新的CSS custom filters(也就是CSS着色器)执行此操作,但在撰写本文时,这并未得到广泛支持。它还需要使用着色器语言(GLSL)。但我发现它至少值得一提。
答案 1 :(得分:1)
示例视频的白色区域越来越多地被后退的黑色区域显示出来。
您可以使用现有的视频+画布来展示基础HTML内容。
制作包含您已制作视频的视频元素。
使用计时器抓取播放视频的帧。强烈建议使用requestAnimationFrame
,因为它会与您的显示刷新同步。
在每个动画循环中,在画布上绘制视频帧。您可以在画布上绘制视频,因为画布可以使用视频元素作为其图像源。
一旦你的黑雾框架在画布上,你可以通过以下方式使画布的任何白色区域透明:
使用context.getImageData
获取画布上每个像素的颜色数据
如果任何像素的颜色为“white-ish”,您可以将该像素的alpha值更改为0(表示透明)。
使用context.putImageData
总的来说:
隐藏播放的视频元素
使用CSS将canvas元素放在您想要显示的html内容上。
创建一个动画循环,在画布上绘制视频帧并将白色像素转换为透明。
html内容将通过播放视频的画布显示,白色像素被完全透明化。
答案 2 :(得分:0)
到目前为止,其他答案假定为2D画布上下文。您可以使用WebGL更有效地完成此任务。这样,所有实际工作都在GPU中完成。
你需要一个片段着色器,它基本上完成了Ken Fyrstenberg的答案中的循环:找到每个像素的亮度,从最大值中减去它(一个,在GLSL中,而不是255),并使用作为阿尔法值。我将在(a)中仅使用绿色通道作为亮度,并且(b)将输出颜色通道设置为黑色。以下是我的表现:
precision lowp float;
uniform sampler2D sampler0;
varying vec2 v_texCoord;
void main(void) {
vec4 color = texture2D(sampler0, v_texCoord);
float alpha = 1.0 - color.g;
gl_FragColor = vec4(0.0, 0.0, 0.0, alpha);
}
对于每个帧,然后,将一个矩形渲染到WebGL画布,将视频作为纹理源,以及上面的片段着色器。 我已经开始编写一个如何执行此操作的示例,但它会采取一些工作。有多大兴趣?请告诉我,如果有足够的需求,我会尽力完成。
编辑:你可以避免使用glfx.js来学习太多关于WebGL的知识。我没有深入研究它,但我认为它可以用视频作为图像源。