Ported QML camera example to QtQuick 2.0 and QtMultimedia 5.0
Removed controls not currently supported on Qt5 platforms and added basic video capture mode Change-Id: I1f188d31af770cfb6ebb65ab5ee4a5467abcfbeb Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
f844d6d9da
commit
0d0e89b1e8
@@ -79,7 +79,6 @@ Item {
|
|||||||
State {
|
State {
|
||||||
name: "invisible"
|
name: "invisible"
|
||||||
PropertyChanges { target: popup; opacity: 0 }
|
PropertyChanges { target: popup; opacity: 0 }
|
||||||
PropertyChanges { target: camera; focus: true }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
State {
|
State {
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** This file is part of the examples of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:BSD$
|
|
||||||
** You may use this file under the terms of the BSD license as follows:
|
|
||||||
**
|
|
||||||
** "Redistribution and use in source and binary forms, with or without
|
|
||||||
** modification, are permitted provided that the following conditions are
|
|
||||||
** met:
|
|
||||||
** * Redistributions of source code must retain the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer.
|
|
||||||
** * Redistributions in binary form must reproduce the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer in
|
|
||||||
** the documentation and/or other materials provided with the
|
|
||||||
** distribution.
|
|
||||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
|
||||||
** the names of its contributors may be used to endorse or promote
|
|
||||||
** products derived from this software without specific prior written
|
|
||||||
** permission.
|
|
||||||
**
|
|
||||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
import QtMultimedia 5.0
|
|
||||||
|
|
||||||
FocusScope {
|
|
||||||
property Camera camera
|
|
||||||
property bool previewAvailable : false
|
|
||||||
|
|
||||||
property alias whiteBalance : wbModesButton.value
|
|
||||||
property alias flashMode : flashModesButton.value
|
|
||||||
property alias exposureCompensation : exposureCompensationButton.value
|
|
||||||
|
|
||||||
property int buttonsPanelWidth: buttonPaneShadow.width
|
|
||||||
|
|
||||||
signal previewSelected
|
|
||||||
id : captureControls
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: buttonPaneShadow
|
|
||||||
width: buttonPanningPane.width + 16
|
|
||||||
height: parent.height
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
color: Qt.rgba(0.08, 0.08, 0.08, 1)
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: buttonPanningPane
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
margins: 8
|
|
||||||
}
|
|
||||||
width: buttonsColumn.width
|
|
||||||
|
|
||||||
contentWidth: buttonsColumn.width
|
|
||||||
contentHeight: buttonsColumn.height
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: buttonsColumn
|
|
||||||
spacing: 8
|
|
||||||
|
|
||||||
FocusButton {
|
|
||||||
camera: captureControls.camera
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraButton {
|
|
||||||
text: "Capture"
|
|
||||||
onClicked: camera.captureImage()
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraPropertyButton {
|
|
||||||
id : flashModesButton
|
|
||||||
value: Camera.FlashOff
|
|
||||||
model: ListModel {
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_flash_auto.png"
|
|
||||||
value: Camera.FlashAuto
|
|
||||||
text: "Auto"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_flash_off.png"
|
|
||||||
value: Camera.FlashOff
|
|
||||||
text: "Off"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_flash_fill.png"
|
|
||||||
value: Camera.FlashOn
|
|
||||||
text: "On"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_flash_redeye.png"
|
|
||||||
value: Camera.FlashRedEyeReduction
|
|
||||||
text: "Red Eye Reduction"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraPropertyButton {
|
|
||||||
id : wbModesButton
|
|
||||||
value: Camera.WhiteBalanceAuto
|
|
||||||
model: ListModel {
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_auto_mode.png"
|
|
||||||
value: Camera.WhiteBalanceAuto
|
|
||||||
text: "Auto"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_white_balance_sunny.png"
|
|
||||||
value: Camera.WhiteBalanceSunlight
|
|
||||||
text: "Sunlight"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_white_balance_cloudy.png"
|
|
||||||
value: Camera.WhiteBalanceCloudy
|
|
||||||
text: "Cloudy"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_white_balance_incandescent.png"
|
|
||||||
value: Camera.WhiteBalanceTungsten
|
|
||||||
text: "Tungsten"
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
icon: "images/camera_white_balance_flourescent.png"
|
|
||||||
value: Camera.WhiteBalanceFluorescent
|
|
||||||
text: "Fluorescent"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExposureCompensationButton {
|
|
||||||
id : exposureCompensationButton
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraButton {
|
|
||||||
text: "View"
|
|
||||||
onClicked: captureControls.previewSelected()
|
|
||||||
visible: captureControls.previewAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraButton {
|
|
||||||
id: quitButton
|
|
||||||
text: "Quit"
|
|
||||||
onClicked: Qt.quit()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: exposureDetails
|
|
||||||
anchors.bottom : parent.bottom
|
|
||||||
anchors.left : parent.left
|
|
||||||
anchors.bottomMargin: 16
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
height: childrenRect.height
|
|
||||||
width: childrenRect.width
|
|
||||||
|
|
||||||
visible : camera.lockStatus == Camera.Locked
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
opacity: 0.4
|
|
||||||
color: "black"
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing : 16
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Av: "+camera.aperture.toFixed(1)
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "white"
|
|
||||||
visible: camera.aperture > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "white"
|
|
||||||
visible: camera.shutterSpped > 0
|
|
||||||
text: "Tv: "+printableExposureTime(camera.shutterSpeed)
|
|
||||||
|
|
||||||
function printableExposureTime(t) {
|
|
||||||
if (t > 3.9)
|
|
||||||
return "Tv: "+t.toFixed() + "\"";
|
|
||||||
|
|
||||||
if (t > 0.24 )
|
|
||||||
return "Tv: "+t.toFixed(1) + "\"";
|
|
||||||
|
|
||||||
if (t > 0)
|
|
||||||
return "Tv: 1/"+(1/t).toFixed();
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "ISO: "+camera.iso.toFixed()
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "white"
|
|
||||||
visible: camera.iso > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ZoomControl {
|
|
||||||
x : 0
|
|
||||||
y : 0
|
|
||||||
width : 100
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
currentZoom: camera.digitalZoom
|
|
||||||
maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
|
|
||||||
onZoomTo: camera.setDigitalZoom(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
** Contact: http://www.qt-project.org/
|
|
||||||
**
|
|
||||||
** This file is part of the examples of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:BSD$
|
|
||||||
** You may use this file under the terms of the BSD license as follows:
|
|
||||||
**
|
|
||||||
** "Redistribution and use in source and binary forms, with or without
|
|
||||||
** modification, are permitted provided that the following conditions are
|
|
||||||
** met:
|
|
||||||
** * Redistributions of source code must retain the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer.
|
|
||||||
** * Redistributions in binary form must reproduce the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer in
|
|
||||||
** the documentation and/or other materials provided with the
|
|
||||||
** distribution.
|
|
||||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
|
||||||
** the names of its contributors may be used to endorse or promote
|
|
||||||
** products derived from this software without specific prior written
|
|
||||||
** permission.
|
|
||||||
**
|
|
||||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
import QtQuick 2.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: flickableList
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
property alias delegate : repeater.delegate
|
|
||||||
|
|
||||||
property variant items: []
|
|
||||||
property int index: 0
|
|
||||||
property int itemWidth : flickableList.width
|
|
||||||
|
|
||||||
function scrollTo(id) {
|
|
||||||
var x = id*flickableList.itemWidth
|
|
||||||
if (flickArea.contentX != x) {
|
|
||||||
centeringAnimation.stop();
|
|
||||||
flickArea.newX = id*flickableList.itemWidth
|
|
||||||
centeringAnimation.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onIndexChanged: scrollTo(index)
|
|
||||||
onWidthChanged: scrollTo(index)
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: flickArea
|
|
||||||
property int newX: 0
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
var x = mapToItem(flickableList, mouseX, mouseY).x
|
|
||||||
|
|
||||||
if (x < flickableList.width/3) {
|
|
||||||
if (flickableList.index > 0)
|
|
||||||
flickableList.scrollTo(flickableList.index-1);
|
|
||||||
} else if (x > flickableList.width*2/3) {
|
|
||||||
if (flickableList.index < flickableList.items.length-1)
|
|
||||||
flickableList.scrollTo(flickableList.index+1);
|
|
||||||
} else {
|
|
||||||
flickableList.clicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyAnimation {
|
|
||||||
id: centeringAnimation
|
|
||||||
target: flickArea
|
|
||||||
properties: "contentX"
|
|
||||||
easing.type: Easing.OutQuad
|
|
||||||
from: flickArea.contentX
|
|
||||||
to: flickArea.newX
|
|
||||||
|
|
||||||
onCompleted: {
|
|
||||||
flickableList.index = flickArea.newX / flickableList.itemWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMovementStarted: {
|
|
||||||
centeringAnimation.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMovementEnded: {
|
|
||||||
var modulo = flickArea.contentX % flickableList.itemWidth;
|
|
||||||
var offset = flickableList.itemWidth / 2;
|
|
||||||
flickArea.newX = modulo < offset ? flickArea.contentX - modulo : flickArea.contentX + (flickableList.itemWidth - modulo);
|
|
||||||
centeringAnimation.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
width: flickableList.width
|
|
||||||
height: flickableList.height
|
|
||||||
contentWidth: items.width
|
|
||||||
contentHeight: items.height
|
|
||||||
flickDeceleration: 4000
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: items
|
|
||||||
Repeater {
|
|
||||||
id: repeater
|
|
||||||
model: flickableList.items.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
159
examples/declarative-camera/PhotoCaptureControls.qml
Normal file
159
examples/declarative-camera/PhotoCaptureControls.qml
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the examples of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.0
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
property Camera camera
|
||||||
|
property bool previewAvailable : false
|
||||||
|
|
||||||
|
property int buttonsPanelWidth: buttonPaneShadow.width
|
||||||
|
|
||||||
|
signal previewSelected
|
||||||
|
signal videoModeSelected
|
||||||
|
id : captureControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPaneShadow
|
||||||
|
width: buttonsColumn.width + 16
|
||||||
|
height: parent.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: Qt.rgba(0.08, 0.08, 0.08, 1)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
margins: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
id: buttonsColumn
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
FocusButton {
|
||||||
|
camera: captureControls.camera
|
||||||
|
visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "Capture"
|
||||||
|
visible: camera.imageCapture.ready
|
||||||
|
onClicked: camera.imageCapture.capture()
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraPropertyButton {
|
||||||
|
id : wbModesButton
|
||||||
|
value: CameraImageProcessing.WhiteBalanceAuto
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
icon: "images/camera_auto_mode.png"
|
||||||
|
value: CameraImageProcessing.WhiteBalanceAuto
|
||||||
|
text: "Auto"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
icon: "images/camera_white_balance_sunny.png"
|
||||||
|
value: CameraImageProcessing.WhiteBalanceSunlight
|
||||||
|
text: "Sunlight"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
icon: "images/camera_white_balance_cloudy.png"
|
||||||
|
value: CameraImageProcessing.WhiteBalanceCloudy
|
||||||
|
text: "Cloudy"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
icon: "images/camera_white_balance_incandescent.png"
|
||||||
|
value: CameraImageProcessing.WhiteBalanceTungsten
|
||||||
|
text: "Tungsten"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
icon: "images/camera_white_balance_flourescent.png"
|
||||||
|
value: CameraImageProcessing.WhiteBalanceFluorescent
|
||||||
|
text: "Fluorescent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "View"
|
||||||
|
onClicked: captureControls.previewSelected()
|
||||||
|
visible: captureControls.previewAvailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: parent.right
|
||||||
|
margins: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
id: bottomColumn
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "Switch to Video"
|
||||||
|
onClicked: captureControls.videoModeSelected()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
id: quitButton
|
||||||
|
text: "Quit"
|
||||||
|
onClicked: Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZoomControl {
|
||||||
|
x : 0
|
||||||
|
y : 0
|
||||||
|
width : 100
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
currentZoom: camera.digitalZoom
|
||||||
|
maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
|
||||||
|
onZoomTo: camera.setDigitalZoom(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
132
examples/declarative-camera/VideoCaptureControls.qml
Normal file
132
examples/declarative-camera/VideoCaptureControls.qml
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the examples of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||||
|
** the names of its contributors may be used to endorse or promote
|
||||||
|
** products derived from this software without specific prior written
|
||||||
|
** permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.0
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
property Camera camera
|
||||||
|
property bool previewAvailable : false
|
||||||
|
|
||||||
|
property int buttonsPanelWidth: buttonPaneShadow.width
|
||||||
|
|
||||||
|
signal previewSelected
|
||||||
|
signal photoModeSelected
|
||||||
|
id : captureControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPaneShadow
|
||||||
|
width: buttonsColumn.width + 16
|
||||||
|
height: parent.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: Qt.rgba(0.08, 0.08, 0.08, 1)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
margins: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
id: buttonsColumn
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
FocusButton {
|
||||||
|
camera: captureControls.camera
|
||||||
|
visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "Record"
|
||||||
|
visible: camera.videoRecorder.recorderStatus == CameraRecorder.LoadedStatus
|
||||||
|
onClicked: camera.videoRecorder.record()
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
id: stopButton
|
||||||
|
text: "Stop"
|
||||||
|
visible: camera.videoRecorder.recorderStatus == CameraRecorder.RecordingStatus
|
||||||
|
onClicked: camera.videoRecorder.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "View"
|
||||||
|
onClicked: captureControls.previewSelected()
|
||||||
|
//don't show View button during recording
|
||||||
|
visible: camera.videoRecorder.actualLocation && !stopButton.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: parent.right
|
||||||
|
margins: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
id: bottomColumn
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
text: "Switch to Photo"
|
||||||
|
onClicked: captureControls.photoModeSelected()
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraButton {
|
||||||
|
id: quitButton
|
||||||
|
text: "Quit"
|
||||||
|
onClicked: Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZoomControl {
|
||||||
|
x : 0
|
||||||
|
y : 0
|
||||||
|
width : 100
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
currentZoom: camera.digitalZoom
|
||||||
|
maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
|
||||||
|
onZoomTo: camera.setDigitalZoom(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,46 +39,33 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: exposureCompensation
|
id: videoPreview
|
||||||
property real value : flickableList.items[flickableList.index]
|
property alias source : player.source
|
||||||
signal clicked
|
signal closed
|
||||||
|
|
||||||
width : 144
|
MediaPlayer {
|
||||||
height: 70
|
id: player
|
||||||
|
autoPlay: true
|
||||||
|
|
||||||
BorderImage {
|
//switch back to viewfinder after playback finished
|
||||||
id: buttonImage
|
onStatusChanged: {
|
||||||
source: "images/toolbutton.sci"
|
if (status == MediaPlayer.EndOfMedia)
|
||||||
width: exposureCompensation.width; height: exposureCompensation.height
|
videoPreview.closed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
VideoOutput {
|
||||||
text: "Ev:"
|
source: player
|
||||||
x: 8
|
anchors.fill : parent
|
||||||
y: 8
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "white"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableList {
|
MouseArea {
|
||||||
anchors.fill: buttonImage
|
anchors.fill: parent
|
||||||
id: flickableList
|
onClicked: {
|
||||||
items: ["-2", "-1.5", "-1", "-0.5", "0", "+0.5", "+1", "+1.5", "+2"]
|
videoPreview.closed();
|
||||||
index: 4
|
|
||||||
|
|
||||||
onClicked: exposureCompensation.clicked()
|
|
||||||
|
|
||||||
delegate: Text {
|
|
||||||
font.pixelSize: 22
|
|
||||||
color: "white"
|
|
||||||
styleColor: "black"
|
|
||||||
width: flickableList.width
|
|
||||||
height: flickableList.height
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
text: flickableList.items[index]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ Item {
|
|||||||
initialZoom = zoomControl.currentZoom
|
initialZoom = zoomControl.currentZoom
|
||||||
}
|
}
|
||||||
|
|
||||||
onMousePositionChanged: {
|
onPositionChanged: {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
var target = initialZoom * Math.pow(2, (initialPos-mouseY)/zoomControl.height);
|
var target = initialZoom * Math.pow(2, (initialPos-mouseY)/zoomControl.height);
|
||||||
target = Math.max(1, Math.min(target, zoomControl.maximumZoom))
|
target = Math.max(1, Math.min(target, zoomControl.maximumZoom))
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
|
|
||||||
TEMPLATE=app
|
TEMPLATE=app
|
||||||
|
TARGET=declarative-camera
|
||||||
|
|
||||||
QT += qtquick1 network multimedia
|
QT += quick qml multimedia
|
||||||
|
|
||||||
contains(QT_CONFIG, opengl) {
|
SOURCES += qmlcamera.cpp
|
||||||
QT += opengl
|
|
||||||
}
|
|
||||||
|
|
||||||
SOURCES += $$PWD/qmlcamera.cpp
|
target.path = $$[QT_INSTALL_EXAMPLES]/qtmultimedia/declarative-camera
|
||||||
!mac:TARGET = qml_camera
|
|
||||||
else:TARGET = QmlCamera
|
|
||||||
|
|
||||||
RESOURCES += declarative-camera.qrc
|
qml.files = declarative-camera.qml \
|
||||||
|
CameraButton.qml \
|
||||||
|
CameraPropertyButton.qml \
|
||||||
|
CameraPropertyPopup.qml \
|
||||||
|
FocusButton.qml \
|
||||||
|
PhotoCaptureControls.qml \
|
||||||
|
PhotoPreview.qml \
|
||||||
|
VideoCaptureControls.qml \
|
||||||
|
VideoPreview.qml \
|
||||||
|
ZoomControl.qml \
|
||||||
|
images
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/qtmultimedia/qml_camera
|
qml.path = $$[QT_INSTALL_EXAMPLES]/qtmultimedia/declarative-camera
|
||||||
sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro
|
|
||||||
sources.path = $$[QT_INSTALL_EXAMPLES]/qtmultimedia/qml_camera
|
|
||||||
|
|
||||||
INSTALLS += target sources
|
INSTALLS += target qml
|
||||||
|
|
||||||
QT+=widgets
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ import QtMultimedia 5.0
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id : cameraUI
|
id : cameraUI
|
||||||
|
|
||||||
|
width: 800
|
||||||
|
height: 480
|
||||||
|
|
||||||
color: "black"
|
color: "black"
|
||||||
state: "PhotoCapture"
|
state: "PhotoCapture"
|
||||||
|
|
||||||
@@ -51,66 +55,97 @@ Rectangle {
|
|||||||
name: "PhotoCapture"
|
name: "PhotoCapture"
|
||||||
StateChangeScript {
|
StateChangeScript {
|
||||||
script: {
|
script: {
|
||||||
camera.visible = true
|
camera.captureMode = Camera.CaptureStillImage
|
||||||
camera.focus = true
|
camera.start()
|
||||||
stillControls.visible = true
|
|
||||||
photoPreview.visible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "PhotoPreview"
|
name: "PhotoPreview"
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "VideoCapture"
|
||||||
StateChangeScript {
|
StateChangeScript {
|
||||||
script: {
|
script: {
|
||||||
camera.visible = false
|
camera.captureMode = Camera.CaptureVideo
|
||||||
stillControls.visible = false
|
camera.start()
|
||||||
photoPreview.visible = true
|
}
|
||||||
photoPreview.focus = true
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "VideoPreview"
|
||||||
|
StateChangeScript {
|
||||||
|
script: {
|
||||||
|
camera.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Camera {
|
||||||
|
id: camera
|
||||||
|
captureMode: Camera.CaptureStillImage
|
||||||
|
|
||||||
|
imageCapture {
|
||||||
|
onImageCaptured: {
|
||||||
|
photoPreview.source = preview
|
||||||
|
stillControls.previewAvailable = true
|
||||||
|
cameraUI.state = "PhotoPreview"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
videoRecorder {
|
||||||
|
resolution: "640x480"
|
||||||
|
frameRate: 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PhotoPreview {
|
PhotoPreview {
|
||||||
id : photoPreview
|
id : photoPreview
|
||||||
anchors.fill : parent
|
anchors.fill : parent
|
||||||
onClosed: cameraUI.state = "PhotoCapture"
|
onClosed: cameraUI.state = "PhotoCapture"
|
||||||
|
visible: cameraUI.state == "PhotoPreview"
|
||||||
focus: visible
|
focus: visible
|
||||||
|
|
||||||
Keys.onPressed : {
|
|
||||||
//return to capture mode if the shutter button is touched
|
|
||||||
if (event.key == Qt.Key_CameraFocus && !event.isAutoRepeat) {
|
|
||||||
cameraUI.state = "PhotoCapture"
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera {
|
VideoPreview {
|
||||||
id: camera
|
id : videoPreview
|
||||||
|
anchors.fill : parent
|
||||||
|
onClosed: cameraUI.state = "VideoCapture"
|
||||||
|
visible: cameraUI.state == "VideoPreview"
|
||||||
|
focus: visible
|
||||||
|
|
||||||
|
//don't load recorded video if preview is invisible
|
||||||
|
source: visible ? camera.videoRecorder.actualLocation : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoOutput {
|
||||||
|
id: viewfinder
|
||||||
|
visible: cameraUI.state == "PhotoCapture" || cameraUI.state == "VideoCapture"
|
||||||
|
|
||||||
x: 0
|
x: 0
|
||||||
y: 0
|
y: 0
|
||||||
width: parent.width - stillControls.buttonsPanelWidth
|
width: parent.width - stillControls.buttonsPanelWidth
|
||||||
height: parent.height
|
height: parent.height
|
||||||
focus: visible //to receive focus and capture key events
|
|
||||||
//captureResolution : "640x480"
|
|
||||||
|
|
||||||
flashMode: stillControls.flashMode
|
source: camera
|
||||||
whiteBalanceMode: stillControls.whiteBalance
|
|
||||||
exposureCompensation: stillControls.exposureCompensation
|
|
||||||
|
|
||||||
onImageCaptured : {
|
|
||||||
photoPreview.source = preview
|
|
||||||
stillControls.previewAvailable = true
|
|
||||||
cameraUI.state = "PhotoPreview"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureControls {
|
PhotoCaptureControls {
|
||||||
id: stillControls
|
id: stillControls
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
camera: camera
|
camera: camera
|
||||||
|
visible: cameraUI.state == "PhotoCapture"
|
||||||
onPreviewSelected: cameraUI.state = "PhotoPreview"
|
onPreviewSelected: cameraUI.state = "PhotoPreview"
|
||||||
|
onVideoModeSelected: cameraUI.state = "VideoCapture"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoCaptureControls {
|
||||||
|
id: videoControls
|
||||||
|
anchors.fill: parent
|
||||||
|
camera: camera
|
||||||
|
visible: cameraUI.state == "VideoCapture"
|
||||||
|
onPreviewSelected: cameraUI.state = "VideoPreview"
|
||||||
|
onPhotoModeSelected: cameraUI.state = "PhotoCapture"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE RCC>
|
|
||||||
<RCC version="1.0">
|
|
||||||
|
|
||||||
<qresource prefix="/">
|
|
||||||
<file>declarative-camera.qml</file>
|
|
||||||
<file>CameraButton.qml</file>
|
|
||||||
<file>CameraPropertyPopup.qml</file>
|
|
||||||
<file>CameraPropertyButton.qml</file>
|
|
||||||
<file>CaptureControls.qml</file>
|
|
||||||
<file>ExposureCompensationButton.qml</file>
|
|
||||||
<file>FlickableList.qml</file>
|
|
||||||
<file>FocusButton.qml</file>
|
|
||||||
<file>PhotoPreview.qml</file>
|
|
||||||
<file>ZoomControl.qml</file>
|
|
||||||
<file>images/camera_auto_mode.png</file>
|
|
||||||
<file>images/camera_camera_setting.png</file>
|
|
||||||
<file>images/camera_flash_auto.png</file>
|
|
||||||
<file>images/camera_flash_fill.png</file>
|
|
||||||
<file>images/camera_flash_off.png</file>
|
|
||||||
<file>images/camera_flash_redeye.png</file>
|
|
||||||
<file>images/camera_white_balance_cloudy.png</file>
|
|
||||||
<file>images/camera_white_balance_flourescent.png</file>
|
|
||||||
<file>images/camera_white_balance_incandescent.png</file>
|
|
||||||
<file>images/camera_white_balance_sunny.png</file>
|
|
||||||
<file>images/toolbutton.png</file>
|
|
||||||
<file>images/toolbutton.sci</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
||||||
@@ -38,51 +38,21 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtWidgets/QDesktopWidget>
|
#include <QQuickView>
|
||||||
#include <QtQuick1/qdeclarativeview.h>
|
#include <QQmlEngine>
|
||||||
#include <QtQml/QQmlEngine>
|
|
||||||
|
|
||||||
#if !defined(QT_NO_OPENGL)
|
int main(int argc, char* argv[])
|
||||||
#include <QtOpenGL/QGLWidget>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
|
QGuiApplication app(argc,argv);
|
||||||
#if defined (Q_WS_X11) || defined (Q_WS_MAC)
|
|
||||||
//### default to using raster graphics backend for now
|
|
||||||
bool gsSpecified = false;
|
|
||||||
for (int i = 0; i < argc; ++i) {
|
|
||||||
QString arg = argv[i];
|
|
||||||
if (arg == "-graphicssystem") {
|
|
||||||
gsSpecified = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gsSpecified)
|
|
||||||
QApplication::setGraphicsSystem("raster");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
|
||||||
const QString mainQmlApp = QLatin1String("qrc:/declarative-camera.qml");
|
|
||||||
QQuickView view;
|
QQuickView view;
|
||||||
#if !defined(QT_NO_OPENGL)
|
|
||||||
view.setViewport(new QGLWidget);
|
|
||||||
#endif
|
|
||||||
view.setSource(QUrl(mainQmlApp));
|
|
||||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
// Qt.quit() called in embedded .qml by default only emits
|
// Qt.quit() called in embedded .qml by default only emits
|
||||||
// quit() signal, so do this (optionally use Qt.exit()).
|
// quit() signal, so do this (optionally use Qt.exit()).
|
||||||
QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));
|
QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));
|
||||||
#if defined(Q_WS_MAEMO_6)
|
view.setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() +
|
||||||
view.setGeometry(application.desktop()->screenGeometry());
|
QLatin1String("/declarative-camera.qml")));
|
||||||
view.showFullScreen();
|
view.resize(800, 480);
|
||||||
#else
|
|
||||||
view.setGeometry(QRect(100, 100, 800, 480));
|
|
||||||
view.show();
|
view.show();
|
||||||
#endif
|
return app.exec();
|
||||||
return application.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user