原文链接 Gareth Stockwell – Pimp my video: shader effects and multimedia
最近一个引起了想当关注的话题就是在Qt Quick程序中应用着色代码的效果。一旦掌握了基础的着色编程语言,在您的项目中使用Qt Quick嵌入着色效果就非常的简单了,结果就是绝妙的虚拟效果用令人惊叹的一小段代码就能实现。
在这篇博客中有之前没有提及到的部分,就是在多媒体内容(视频回放,或者视频取景器)上应用着色效果就和在其它任何QML元素上应用一样简单。本篇博客演示了混合着色编程与QtMultimedia后大家都能实现的一些效果。
大家都能实现的效果的最好的证明就是……来一段演示。让我们现在就开始!
在桌面Linux,Qt 5环境下运行的qmlvideofx演示 |
上面的视频展示了一个Qt Quick 2演示程序,运行在桌面Linux环境上。除了一些辅助的C++代码(监听scene graph信号以计算帧率和从文件系统中读取着色程序)之外,程序整个由QML写成。
之前也提到过,Qt Quick 2通过ShaderEffect这个QML元素内置了对着色效果的支持。在视频或取景器中使用这些元素来实现着色效果确实不比在其他任何QML元素上实现更复杂。为了说明这一点,下面的代码片段展示了对文件中播放的视频剪辑中应用时变抖动效果(time-varying wobble effect)。
import QtQuick 2.0
import QtMultimedia 5.0Rectangle {
width: 600
height: 400MediaPlayer {
id: mediaPlayer
autoplay: true
source: "test.ogg"
}VideoOutput {
id: videoOutput
anchors.fill: parent
source: mediaPlayer
}ShaderEffect {
anchors.fill: parent// Properties which will be passed into the shader as uniforms
property real amplitude: 0.02
property real frequency: 20
property real time: 0NumberAnimation on time {
loops: Animation.Infinite
from: 0
to: Math.PI * 2
duration: 600
}property variant source: ShaderEffectSource {
sourceItem: videoOutput
hideSource: true
}fragmentShader: "
uniform highp float amplitude;
uniform highp float frequency;
uniform highp float time;
uniform sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
void main() {
highp vec2 p = sin(time + frequency * qt_TexCoord0);
highp vec2 tc = qt_TexCoord0 + amplitude * vec2(p.y, -p.x);
gl_FragColor = qt_Opacity * texture2D(source, tc);
}
"
}
}
在取景器流而不是视频回放中应用这个效果仅仅是简单地将Video元素替换为Camera元素的事。
在qmlvideofx演示中,每一种效果的实现继承自ShaderEffect的QML元素;这些元素在用户从菜单选择了对应效果之后动态加载、应用在视频内容上。类似的,不同的输入(图像,视频以及摄像头)也是在需要的时候由QML元素动态地加载。
每种特效支持的参数设置(比如像素化中的“粒度”、放大镜中的“半径和衍射”)暴露给一个ListModel,这个ListModel被用于创建一些滑动条来调整这些参数。
qmlvideofx演示的源码保存在qtmultimedia仓库中:
https://qt.gitorious.org/qt/qtmultimedia/trees/master/examples/video/qmlvideofx
在Qt 5.0发布之前,您得从源码中编译、运行这个演示。如何编译的介绍可以以这里作为参考。必要的Qt模块的子集可以按照下述方式克隆:
$QTDIR/init-repository --module-subset=qtbase,qtdeclarative,qtjsbackend,qtmultimedia,qtxmlpatterns
由于Qt Quick 1没有内置着色效果的支持,所以需要Qt4.7.4及后续版本提供的Qt.labs.shaders插件。Qt 4版本的演示可以从这里获取:
https://qt.gitorious.org/qt-mobility/qt-mobility/trees/master/demos/video/qmlvideofx
除了能在桌面环境(已在Linux与Windows上测试)运行之外,Qt 4版本的演示也能在移动设备上运行——下面的视频展示了运行在Symbian设备(Nokia C-701)上的演示程序。
在塞班(Nokia C-701)设备,Qt 4环境下运行的qmlvideofx演示 |
眼尖的读者可能注意到了这个演示程序和桌面版本有一些不太明显的区别——感谢Qt Quick的灵活性,使得这个不同可以通过替换描述布局的一个单一QML文件来实现。
需要指出的是,这个演示不能在现有版本的Symbian设备上运行。原因就在于它需要视频解码器能够使用OpenGLES引擎作为纹理的输出。在之后的Symbian发布中会加入一个EGL扩展来允许视频与图形栈以这种方式合作(EGL_NOK_image_endpoint2)。一旦合作可用,QtMultimediaKit会自动选择使用它(详见QTMOBILITY-1818),之后演示程序就能正常工作。
然而,您可以现在就在Nokia N9上运行这个演示程序 – 就像下面的视频里的那样。
在MeeGo Harmattan(Nokia N9)设备,Qt 4环境下运行的qmlvideofx演示 |
如果您之前还没有对着色效果的潜力感到兴奋,希望现在能激动起来。下面是一些其他人结合Qt/QML使用的例子的链接。