Merge remote-tracking branch 'origin/release' into stable
Change-Id: I900412b4c6f894dec27b8158d498b2ff18404ced
BIN
examples/multimedia/video/doc/images/qmlvideofx-camera-glow.jpg
Normal file
|
After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 200 KiB |
|
After Width: | Height: | Size: 62 KiB |
BIN
examples/multimedia/video/doc/images/qmlvideofx-effects-menu.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 273 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 215 KiB |
@@ -46,31 +46,25 @@ advanced functionality - in this case, C++ code is used to calculate the QML
|
||||
frame rate. This value is rendered in QML in a semi-transparent item
|
||||
overlaid on the video content.
|
||||
|
||||
Finally, this application demonstrates the use of different top-level QML
|
||||
files to handle different physical screen sizes. On small-screen devices,
|
||||
menus are by default hidden, and only appear when summoned by a gesture.
|
||||
Large-screen devices show a more traditional layout in which menus are
|
||||
displayed around the video content pane.
|
||||
|
||||
The following screenshots show shader effects being applied. In each case,
|
||||
the effect is implemented using a fragment shader.
|
||||
|
||||
Here we see an edge detection algorithm being applied to a video clip
|
||||
(\l{http://orange.blender.org/}{Elephant's Dream from blender.org}).
|
||||
\image qmlvideofx-video-edgedetection.png
|
||||
(\l{http://durian.blender.org/}{Sintel from blender.org}).
|
||||
\image qmlvideofx-video-edgedetection.jpg
|
||||
|
||||
This image shows a page curl effect, applied to the same video clip.
|
||||
\image qmlvideofx-video-pagecurl.png
|
||||
\image qmlvideofx-video-pagecurl.jpg
|
||||
|
||||
Here we see a 'glow' effect (edge detection plus colour quantization) being
|
||||
applied to the camera viewfinder.
|
||||
\image qmlvideofx-camera-glow.png
|
||||
\image qmlvideofx-camera-glow.jpg
|
||||
|
||||
This image shows a 'lens magnification' effect applied to the viewfinder.
|
||||
\image qmlvideofx-camera-magnify.png
|
||||
This image shows a 'wobble' effect applied to the viewfinder.
|
||||
\image qmlvideofx-camera-wobble.jpg
|
||||
|
||||
The application includes many more effects than the ones shown here - look
|
||||
for Effect*.qml files in the list above to see the full range.
|
||||
for Effect*.qml files in the list of files below to see the full range.
|
||||
|
||||
\section1 Application structure
|
||||
|
||||
@@ -197,11 +191,8 @@ vertical dividing line, which can be dragged left / right by the user. Finally,
|
||||
a \l{video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml}{ParameterPanel} item
|
||||
renders the sliders corresponding to each effect parameter.
|
||||
|
||||
Here is the source selection menu:
|
||||
\image qmlvideofx-source-menu.png
|
||||
|
||||
And here is the effect selection menu:
|
||||
\image qmlvideofx-effects-menu.png
|
||||
Here is the effect selection menu:
|
||||
\image qmlvideofx-effects-menu.jpg
|
||||
|
||||
\section1 Calculating and displaying QML painting rate
|
||||
|
||||
|
||||
@@ -122,7 +122,8 @@ int main(int argc, char *argv[])
|
||||
viewer.setTitle("qmlvideofx");
|
||||
viewer.setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint |
|
||||
Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
||||
viewer.setMinimumSize(QSize(640, 360));
|
||||
viewer.setMinimumSize(QSize(1280, 720));
|
||||
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
|
||||
viewer.show();
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ Rectangle {
|
||||
Rectangle {
|
||||
anchors { fill: parent; margins: 1 }
|
||||
color: mouseArea.pressed ? bgColorSelected : bgColor
|
||||
radius: 0.1 * height
|
||||
|
||||
Text {
|
||||
id: text
|
||||
@@ -68,7 +67,7 @@ Rectangle {
|
||||
text: root.text
|
||||
anchors { fill: parent; margins: scaledMargin }
|
||||
font.pixelSize: fontSize
|
||||
color: mouseArea.pressed ? bgColor : textColor
|
||||
color: textColor
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
@@ -49,28 +49,40 @@ Rectangle {
|
||||
signal openVideo
|
||||
signal close
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
Rectangle {
|
||||
height: itemHeight
|
||||
width: itemHeight
|
||||
color: "transparent"
|
||||
anchors.right: parent.right
|
||||
Image {
|
||||
id: menu
|
||||
source: "qrc:///images/icon_Menu.png"
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: scaledMargin
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: fileOpen.state == "expanded" ? fileOpen.state = "collapsed" : fileOpen.state = "expanded"
|
||||
|
||||
Rectangle {
|
||||
id: menuField
|
||||
height: itemHeight
|
||||
width: itemHeight
|
||||
color: "transparent"
|
||||
anchors.right: parent.right
|
||||
Image {
|
||||
id: menu
|
||||
source: "qrc:///images/icon_Menu.png"
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: scaledMargin
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: fileOpen.state == "expanded" ? fileOpen.state = "collapsed" : fileOpen.state = "expanded"
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors {
|
||||
top: menuField.bottom
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
topMargin: 10
|
||||
}
|
||||
|
||||
spacing: 10
|
||||
visible: fileOpen.state == "expanded"
|
||||
|
||||
Rectangle {
|
||||
width: 0.9 * parent.width
|
||||
height: 1
|
||||
@@ -81,8 +93,10 @@ Rectangle {
|
||||
text: "Start camera"
|
||||
height: itemHeight
|
||||
width: parent.width
|
||||
onClicked: root.openCamera()
|
||||
active: fileOpen.state == "expanded"
|
||||
onClicked: {
|
||||
fileOpen.state = "collapsed"
|
||||
root.openCamera()
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 0.9 * parent.width
|
||||
@@ -94,8 +108,10 @@ Rectangle {
|
||||
text: "Open image"
|
||||
height: itemHeight
|
||||
width: parent.width
|
||||
onClicked: root.openImage()
|
||||
active: fileOpen.state == "expanded"
|
||||
onClicked: {
|
||||
fileOpen.state = "collapsed"
|
||||
root.openImage()
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 0.9 * parent.width
|
||||
@@ -107,8 +123,10 @@ Rectangle {
|
||||
text: "Open video"
|
||||
height: itemHeight
|
||||
width: parent.width
|
||||
onClicked: root.openVideo()
|
||||
active: fileOpen.state == "expanded"
|
||||
onClicked: {
|
||||
fileOpen.state = "collapsed"
|
||||
root.openVideo()
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 0.9 * parent.width
|
||||
@@ -120,8 +138,10 @@ Rectangle {
|
||||
text: "Reset"
|
||||
height: itemHeight
|
||||
width: parent.width
|
||||
onClicked: root.close()
|
||||
active: fileOpen.state == "expanded"
|
||||
onClicked: {
|
||||
fileOpen.state = "collapsed"
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 0.9 * parent.width
|
||||
|
||||
@@ -80,7 +80,7 @@ Rectangle {
|
||||
id: parameterPanel
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: listview.left
|
||||
right: effectName.left
|
||||
bottom: parent.bottom
|
||||
margins: scaledMargin
|
||||
leftMargin: scaledMargin + itemHeight
|
||||
@@ -88,46 +88,50 @@ Rectangle {
|
||||
gripSize: d.gripSize
|
||||
height: root.itemHeight * 2.5
|
||||
width: root.itemWidth * 3
|
||||
|
||||
}
|
||||
|
||||
|
||||
Button {
|
||||
id: effectName
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: perfHolder.top
|
||||
top: content.bottom
|
||||
margins: scaledMargin
|
||||
}
|
||||
|
||||
text: "No effect"
|
||||
width: itemWidth * 2
|
||||
height: itemHeight
|
||||
onClicked: {
|
||||
effectName.visible = false
|
||||
listview.visible = true
|
||||
lvbg.visible = true
|
||||
}
|
||||
color: "#303030"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: lvbg
|
||||
width: itemWidth * 2
|
||||
color: "black"
|
||||
opacity: 0.8
|
||||
visible: false
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: perfHolder.top
|
||||
top: parent.top
|
||||
margins: scaledMargin
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
width: itemWidth * 2
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: perfHolder.top
|
||||
top: parent.top
|
||||
margins: scaledMargin
|
||||
}
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
|
||||
model: EffectSelectionList {}
|
||||
delegate: effectDelegate
|
||||
|
||||
highlight: Rectangle { color: "#14aaff"; radius: 5 }
|
||||
highlightFollowsCurrentItem: true
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
clip: true
|
||||
focus: true
|
||||
|
||||
@@ -139,6 +143,7 @@ Rectangle {
|
||||
onClicked: {
|
||||
content.effectSource = source
|
||||
listview.visible = false
|
||||
lvbg.visible = false
|
||||
effectName.text = name
|
||||
effectName.visible = true
|
||||
parameterPanel.model = content.effect.parameters
|
||||
@@ -146,6 +151,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -213,8 +219,8 @@ Rectangle {
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
NumberAnimation { target: fileOpen; property: "width"; duration: 400 }
|
||||
NumberAnimation { target: fileOpen; property: "opacity"; duration: 400 }
|
||||
NumberAnimation { target: fileOpen; property: "width"; duration: 100 }
|
||||
NumberAnimation { target: fileOpen; property: "opacity"; duration: 100 }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||