×
Namespaces

Variants
Actions
(Difference between revisions)

Tutorial: Step-by-step to create a timer-based camera

From Nokia Developer Wiki
Jump to: navigation, search
Slocan (Talk | contribs)
m (Slocan -)
hamishwillee (Talk | contribs)
m (Hamishwillee -)
 
(12 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Category:Draft]]
+
[[Category:Qt Mobility]][[Category:Qt Quick]][[Category:Qt]][[Category:Symbian]][[Category:MeeGo Harmattan]][[Category:Code Examples]][[Category:Camera]]
 
{{Abstract|This article explains how to create with QML a camera application taking mutliple-shots using timers. We will explore step-by-step how to start such an application, and how to add features one at a time. }}
 
{{Abstract|This article explains how to create with QML a camera application taking mutliple-shots using timers. We will explore step-by-step how to start such an application, and how to add features one at a time. }}
 +
 +
{{Note|This is an entry in the [[PureView Imaging Competition 2012Q2]]}}
  
 
{{ArticleMetaData <!-- v1.2 -->
 
{{ArticleMetaData <!-- v1.2 -->
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
+
|sourcecode= [[Media:CameraTimer-Symbian.tar.gz]] [[Media:CameraTimer-Harmattan.tar.gz]]<!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
+
|devices= N8, N950, N9<!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 
|sdk= SDK 1.2.1<!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
 
|sdk= SDK 1.2.1<!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
 
|platform= All platforms with Qt Multimedia 1.1<!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|platform= All platforms with Qt Multimedia 1.1<!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
 
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
+
|signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|capabilities= UserEnvironment<!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= UserEnvironment<!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|keywords= QML,Camera,Timer<!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
|keywords= QML,Camera,Timer<!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
Line 17: Line 19:
 
|translated-from-title= <!-- Title only -->
 
|translated-from-title= <!-- Title only -->
 
|translated-from-id= <!-- Id of translated revision -->
 
|translated-from-id= <!-- Id of translated revision -->
|review-by=<!-- After re-review: [[User:username]] -->
+
|review-by= <!-- After re-review: [[User:username]] -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 
|creationdate= 20120511<!-- Format YYYYMMDD -->
 
|creationdate= 20120511<!-- Format YYYYMMDD -->
|author= [[User:Slocan]]<!-- Display as link [[User:username]] -->
+
|author= [[User:Slocan]]
 
}}
 
}}
  
 
== Introduction ==
 
== Introduction ==
  
Qt Multimedia 1.1 introduced the Camera element in QML, which provides an easy to use entry-point to the world of cell-phone photography. We will see in this article how to use this element and then augment it step-by-step with timer-based features, and how to display the previews taken from the camera.
+
Qt Multimedia 1.1 introduced the Camera<ref name="camera">[http://doc.qt.nokia.com/qtmobility-1.2/qml-camera.html QML Camera], Camera element API doc.</ref> element in QML, which provides an easy to use entry-point to the world of cell-phone photography. We will see in this article how to use this element and then augment it step-by-step with timer-based features, and how to display the previews taken from the camera.
  
[[File:2012-05-11_14-27-16.png|400px]]
+
[[File:2012-05-11 14-27-16.png|400px]]
  
 
== Initial Setup ==
 
== Initial Setup ==
  
To start writing the application, let's create a new project for a Qt Quick Application in the Qt SDK for our platform. The example and source code provided here is for Meego Harmattan and Symbian^3 and Nokia Belle. The only difference in the QML files is at the top of the file, to import the Qt-Components that is appropriate for each. On Symbian, the Camera element requires the UserEnvironment capability. We also need to enable Qt Multimedia Kit, and Qt Components (only required to simplify the creation of the buttons in our examples). Here are the modifications to the .pro file:
+
To start writing the application, let's create a new project for a Qt Quick Application in the Qt SDK for our platform. The example and source code provided here is for Meego Harmattan and Symbian^3 and Nokia Belle. The only difference in the QML files is at the top of the file, to import the Qt-Components that is appropriate for each. On Symbian, the Camera<ref name="camera" /> element requires the UserEnvironment capability. We also need to enable Qt Multimedia Kit, and Qt Components (only required to simplify the creation of the buttons in our examples). Here are the modifications to the .pro file:
<code>
+
<code css>
 
## Add the UserEnvironment capability to use the Camera element on Symbian
 
## Add the UserEnvironment capability to use the Camera element on Symbian
 
symbian:TARGET.CAPABILITY += UserEnvironment
 
symbian:TARGET.CAPABILITY += UserEnvironment
Line 50: Line 52:
 
== Capture One Image ==
 
== Capture One Image ==
  
In this first example, we create a simple interface with the Camera element, and we trigger the image capture with a single button. This button calls the function ''camera.captureImage()'' on the Camera element, which triggers the capture. The Camera element sends the signal ImageCaptured, followed by ImageSaved once the image is written to disk.
+
In this first example, we create a simple interface with the Camera<ref name="camera" /> element, and we trigger the image capture with a single button. This button calls the function ''camera.captureImage()'' on the Camera element, which triggers the capture. The Camera element sends the signal ImageCaptured, followed by ImageSaved once the image is written to disk.
During testing, some phones (in particular the N950) appear to be having trouble trying to display the Camera element when saving the image to disk. For this reason, we use these 2 signals to hide the element for a short time to let it complete its write.
+
During testing, some phones (in particular the N950) appear to be having trouble trying to display the Camera<ref name="camera" /> element when saving the image to disk. For this reason, we use these 2 signals to hide the element for a short time to let it complete its write.
  
[[File:2012-05-11_14-30-40.png|400px]]
+
To simplify the example, we leave most of the settings for the Camera element to its default, which means it will have autofocus, auto-ISO, no zoom... The default settings are quite good for most cases, unless you have something specific in mind. 2 settings are included in the example to show how to use them should you want to. The whiteBalanceMode setting is left to its default, and the Flash is turned off (just so it wouldn't illuminate the whole room every time the app is tested!).
 +
 
 +
[[File:2012-05-11 14-30-40.png|400px]]
  
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page1 element. The Page1.qml file contains the source for this example.
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page1 element. The Page1.qml file contains the source for this example.
  
<code>
+
<code css>
 
import QtQuick 1.1
 
import QtQuick 1.1
 
import com.nokia.meego 1.1
 
import com.nokia.meego 1.1
Line 109: Line 113:
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page2 element. The Page2.qml file contains the source for this example.
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page2 element. The Page2.qml file contains the source for this example.
  
In this example, we will add a self-timer, so the photo happens with a configurable delay. To do so, we use the Timer element.
+
In this example, we will add a self-timer, so the photo happens with a configurable delay. To do so, we use the Timer<ref name="timer">[http://doc.qt.nokia.com/4.7/qml-timer.html QML Timer]</ref> element.
<code>
+
<code css>
 
   Timer {
 
   Timer {
 
       id: delayTimer
 
       id: delayTimer
Line 120: Line 124:
 
</code>
 
</code>
  
This Timer is called with ''delayTimer.start()'' called from the button created in the previous example (see Page2.qml). To create the configuration dialog, we use a SelectionDialog with a few options:
+
This Timer<ref name="timer" /> is called with ''delayTimer.start()'' called from the button created in the previous example (see Page2.qml). To create the configuration dialog, we use a SelectionDialog<ref name="SelectionDialog" /> with a few options:
<code>
+
<code css>
 
   SelectionDialog {
 
   SelectionDialog {
 
       id: selectDelay
 
       id: selectDelay
Line 139: Line 143:
 
When the "Start Capture" button is pressed, the timer will grab its delay value from the SelectionDialog's selected item, and will wait for that long before triggering the Camera's element capture.
 
When the "Start Capture" button is pressed, the timer will grab its delay value from the SelectionDialog's selected item, and will wait for that long before triggering the Camera's element capture.
  
[[File:2012-05-11_14-29-52.png|400px]]
+
[[File:2012-05-11 14-29-52.png|400px]]
  
 
== Adding multiple sequential captures ==
 
== Adding multiple sequential captures ==
Line 145: Line 149:
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page3 element. The Page3.qml file contains the source for this example.
 
'''Note:''' If you downloaded the included archive, edit the file main.qml to have it load the Page3 element. The Page3.qml file contains the source for this example.
  
In this example, we add another Timer and a count value which will be used to trigger the camera multiple times in a row, with a configurable delay between the shots. For the configuration, we use them same method as for the previous example, a SelectionDialog, with a list of acceptable values. Note that, in this example, the frequency value is the delay that the app will wait in-between shots, excluding the capture time.The timer only starts once the previous capture has completed its write to disk. This can easily be changed, but can cause some shots to be missed if the Camera element is not ready yet when we trigger the next capture.
+
In this example, we add another Timer<ref name="timer" /> and a count value which will be used to trigger the camera multiple times in a row, with a configurable delay between the shots. For the configuration, we use them same method as for the previous example, a SelectionDialog<ref name="SelectionDialog">[http://doc.qt.nokia.com/qt-components-symbian/qml-selectiondialog.html QML SelectionDialog]</ref>, with a list of acceptable values. Note that, in this example, the frequency value is the delay that the app will wait in-between shots, excluding the capture time.The timer only starts once the previous capture has completed its write to disk. This can easily be changed, but can cause some shots to be missed if the Camera element is not ready yet when we trigger the next capture.
  
[[File:2012-05-11_14-28-49.png|400px]]
+
[[File:2012-05-11 14-28-49.png|400px]]
  
 
To trigger the next timer, we use the ImageSaved signal that is sent by the Camera element, to re-start the timer.
 
To trigger the next timer, we use the ImageSaved signal that is sent by the Camera element, to re-start the timer.
<code>
+
<code css>
 
           onImageSaved: {
 
           onImageSaved: {
 
                   camera.visible = true
 
                   camera.visible = true
Line 165: Line 169:
 
In this last example, we will add a ListView item which will list all the preview images that have been taken by the application. We create a custom ShowPreview element, which contains the ListView, and its associated ListModel (name previewList). We also use a helper function add(item) which appends the new image to the model. This is called with ‘’showPreview.add({"path":path})’’ when the ImageSaved signal is sent by the Camera element.
 
In this last example, we will add a ListView item which will list all the preview images that have been taken by the application. We create a custom ShowPreview element, which contains the ListView, and its associated ListModel (name previewList). We also use a helper function add(item) which appends the new image to the model. This is called with ‘’showPreview.add({"path":path})’’ when the ImageSaved signal is sent by the Camera element.
  
[[File:2012-05-11_14-27-16.png|400px]]
+
[[File:2012-05-11 14-27-16.png|400px]]
  
<code>
+
<code css>
 
import QtQuick 1.1
 
import QtQuick 1.1
  
Line 200: Line 204:
  
 
Although these are fairly simple examples, they can easily be augmented with other simple features. Here are a few ideas to continue this project:
 
Although these are fairly simple examples, they can easily be augmented with other simple features. Here are a few ideas to continue this project:
- Exposure bracketing: Use this method to take 3 shots in a row, setting a different Exposure Compensation for each shot. These can then be post-processed into an HDR photo (High Dynamic Range).
+
* If we would like to take shots as fast as possible, it would be beneficial is lock the Camera settings after the first exposures. For example, keep the focus that the Camera element found in the first image for the ones after. This would reduce the amount of time it takes per capture, and the shots would be closer to each other.
- Additional control of settings: Use the QML declarative camera example to see how to control all the Camera settings, and how to augment our example with manual control over those.
+
* Exposure bracketing: Use this method to take 3 shots in a row, setting a different Exposure Compensation for each shot. These can then be post-processed into an HDR photo (High Dynamic Range).
- Flash "bracketing": Take 2 sequential shots, one with flash, one without, so they can be compared afterwards, in order to keep the better one.
+
* Additional control of settings: Use the QML declarative camera example to see how to control all the Camera settings, and how to augment our example with manual control over those.
 +
* Flash "bracketing": Take 2 sequential shots, one with flash, one without, so they can be compared afterwards, in order to keep the better one.
 +
 
 +
== References ==
 +
<references />

Latest revision as of 08:29, 14 June 2013

This article explains how to create with QML a camera application taking mutliple-shots using timers. We will explore step-by-step how to start such an application, and how to add features one at a time.

Note.pngNote: This is an entry in the PureView Imaging Competition 2012Q2

Article Metadata
Code ExampleTested with
SDK: SDK 1.2.1
Devices(s): N8, N950, N9
Compatibility
Platform(s): All platforms with Qt Multimedia 1.1
Symbian
Platform Security
Capabilities: UserEnvironment
Article
Keywords: QML,Camera,Timer
Created: Slocan (11 May 2012)
Last edited: hamishwillee (14 Jun 2013)

Contents

[edit] Introduction

Qt Multimedia 1.1 introduced the Camera[1] element in QML, which provides an easy to use entry-point to the world of cell-phone photography. We will see in this article how to use this element and then augment it step-by-step with timer-based features, and how to display the previews taken from the camera.

2012-05-11 14-27-16.png

[edit] Initial Setup

To start writing the application, let's create a new project for a Qt Quick Application in the Qt SDK for our platform. The example and source code provided here is for Meego Harmattan and Symbian^3 and Nokia Belle. The only difference in the QML files is at the top of the file, to import the Qt-Components that is appropriate for each. On Symbian, the Camera[1] element requires the UserEnvironment capability. We also need to enable Qt Multimedia Kit, and Qt Components (only required to simplify the creation of the buttons in our examples). Here are the modifications to the .pro file:

## Add the UserEnvironment capability to use the Camera element on Symbian
symbian:TARGET.CAPABILITY += UserEnvironment
 
# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
CONFIG += mobility
## Add Qt Multimedia libraries
MOBILITY += multimedia
 
## Add dependency to Symbian components
CONFIG += qt-components

[edit] Capture One Image

In this first example, we create a simple interface with the Camera[1] element, and we trigger the image capture with a single button. This button calls the function camera.captureImage() on the Camera element, which triggers the capture. The Camera element sends the signal ImageCaptured, followed by ImageSaved once the image is written to disk. During testing, some phones (in particular the N950) appear to be having trouble trying to display the Camera[1] element when saving the image to disk. For this reason, we use these 2 signals to hide the element for a short time to let it complete its write.

To simplify the example, we leave most of the settings for the Camera element to its default, which means it will have autofocus, auto-ISO, no zoom... The default settings are quite good for most cases, unless you have something specific in mind. 2 settings are included in the example to show how to use them should you want to. The whiteBalanceMode setting is left to its default, and the Flash is turned off (just so it wouldn't illuminate the whole room every time the app is tested!).

2012-05-11 14-30-40.png

Note: If you downloaded the included archive, edit the file main.qml to have it load the Page1 element. The Page1.qml file contains the source for this example.

import QtQuick 1.1
import com.nokia.meego 1.1
import QtMultimediaKit 1.1
 
Page {
Row {
anchors.fill: parent
Item {
height: parent.height
width: parent.width - captureButton.width
 
Camera {
id: camera
 
anchors.fill: parent
flashMode: Camera.FlashOff
whiteBalanceMode: Camera.WhiteBalanceAuto
 
onImageCaptured : {
console.debug("Captured Image:" +preview);
// Hide the Camera element while the image is being written to disk
camera.visible = false
}
 
onImageSaved: {
console.log("Image saved:"+path);
// The image has been written, show the element again
camera.visible = true
}
 
onCaptureFailed: {
console.log("Failed: "+message)
}
}
}
 
Button {
id: captureButton
height: 100
 
text: qsTr("Capture Image")
onClicked: camera.captureImage()
}
}
}

[edit] Adding a delay

Note: If you downloaded the included archive, edit the file main.qml to have it load the Page2 element. The Page2.qml file contains the source for this example.

In this example, we will add a self-timer, so the photo happens with a configurable delay. To do so, we use the Timer[2] element.

   Timer {
id: delayTimer
interval: selectDelay.model.get(selectDelay.selectedIndex).value
onTriggered: {
camera.captureImage()
}
}

This Timer[2] is called with delayTimer.start() called from the button created in the previous example (see Page2.qml). To create the configuration dialog, we use a SelectionDialog[3] with a few options:

   SelectionDialog {
id: selectDelay
titleText: "Camera will be triggered after the initial:"
selectedIndex: 0
 
model: ListModel {
// The value is in microseconds
ListElement { name: "2 second"; value: 2000 }
ListElement { name: "5 seconds"; value: 5000 }
ListElement { name: "10 seconds"; value: 10000 }
ListElement { name: "Immidiately"; value: 0 }
}
}

When the "Start Capture" button is pressed, the timer will grab its delay value from the SelectionDialog's selected item, and will wait for that long before triggering the Camera's element capture.

2012-05-11 14-29-52.png

[edit] Adding multiple sequential captures

Note: If you downloaded the included archive, edit the file main.qml to have it load the Page3 element. The Page3.qml file contains the source for this example.

In this example, we add another Timer[2] and a count value which will be used to trigger the camera multiple times in a row, with a configurable delay between the shots. For the configuration, we use them same method as for the previous example, a SelectionDialog[3], with a list of acceptable values. Note that, in this example, the frequency value is the delay that the app will wait in-between shots, excluding the capture time.The timer only starts once the previous capture has completed its write to disk. This can easily be changed, but can cause some shots to be missed if the Camera element is not ready yet when we trigger the next capture.

2012-05-11 14-28-49.png

To trigger the next timer, we use the ImageSaved signal that is sent by the Camera element, to re-start the timer.

           onImageSaved: {
camera.visible = true
if (cameraTimer.count < selectNumberShots.model.get(selectNumberShots.selectedIndex).value) {
cameraTimer.start()
}
}

[edit] Adding preview images

Note: If you downloaded the included archive, edit the file main.qml to have it load the Page4 element. The Page4.qml file contains the source for this example.

In this last example, we will add a ListView item which will list all the preview images that have been taken by the application. We create a custom ShowPreview element, which contains the ListView, and its associated ListModel (name previewList). We also use a helper function add(item) which appends the new image to the model. This is called with ‘’showPreview.add({"path":path})’’ when the ImageSaved signal is sent by the Camera element.

2012-05-11 14-27-16.png

import QtQuick 1.1
 
Item {
function add(item) {
previewList.append(item)
}
 
ListView {
anchors.fill: parent
model: previewList
delegate: showImage
}
 
Component {
id: showImage
Image {
source: path
width: 110
height: 110
}
}
 
ListModel {
id: previewList
}
 
}

[edit] Where to go from here

Although these are fairly simple examples, they can easily be augmented with other simple features. Here are a few ideas to continue this project:

  • If we would like to take shots as fast as possible, it would be beneficial is lock the Camera settings after the first exposures. For example, keep the focus that the Camera element found in the first image for the ones after. This would reduce the amount of time it takes per capture, and the shots would be closer to each other.
  • Exposure bracketing: Use this method to take 3 shots in a row, setting a different Exposure Compensation for each shot. These can then be post-processed into an HDR photo (High Dynamic Range).
  • Additional control of settings: Use the QML declarative camera example to see how to control all the Camera settings, and how to augment our example with manual control over those.
  • Flash "bracketing": Take 2 sequential shots, one with flash, one without, so they can be compared afterwards, in order to keep the better one.

[edit] References

  1. 1.0 1.1 1.2 1.3 QML Camera, Camera element API doc.
  2. 2.0 2.1 2.2 QML Timer
  3. 3.0 3.1 QML SelectionDialog
This page was last modified on 14 June 2013, at 08:29.
94 page views in the last 30 days.
×