A couple of days ago I received an email from Stefan Plattner asking how to integrate photo capture into an application without using the standard camera user interface. Since I’ve heard this question a couple of times I thought I would respond to his email via a blog posting.
His question was:
I read some posts on your excellent weblog (http://www.christec.co.nz/blog/). Maybe you can give me some answers regarding “camera programming” for Windows Mobile.
I’m starting to develop an application for the Compact Framework 2.0 (PocketPC) and wanted to show the real-time camera image in a frame (directly in the application, not through “CameraCaptureDialog()”). In a second step it would be nice to capture the current image on a button click. Do you know if there is some sample code (managed or unmanaged) out there? Do you have any experience with this topic?
I apologize, if I bother you with this email, but I couldn’t find useful information anywhere on the net.
I don’t have a code sample that does exactly what Stefan wants, but can give a couple of pointers to code samples that may be modifiable to suit his needs.
Prior to Windows Mobile 5.0 there was no standardised camera API, meaning it’s difficult to provide an answer for Windows Mobile 2003 or prior. However with Windows Mobile 5.0 and above there are three standardised APIs that can be used to work with the camera at various levels of abstraction.
Unfortunately the two APIs that are easily accessible from managed code both require user input in order to capture an image and don’t allow much flexibility in the user interface presented during image capture. The third API for accessing the camera functionality is called DirectShow. This is a COM based API that is significantly more complex to utilise due to it’s implementation technology and the low level nature of the API.
Some code samples that you may find a useful starting point include:
- CameraCapture code sample – The Windows Mobile 5.0 / 6 SDKs include a code sample written in native C++ to demonstrate how to setup a DirectShow filter graph in order to capture video or still images at a press of a button.
- Marcus Perryman’s Timed Camera Capture blog posting discusses how to modify the CameraCapture code sample to become a small DLL that can be called from a C# application to automatically take photos at a timed interval.
- As an alternative MSDN Forums contains a thread titled “SendKeys” which discusses automating the existing CameraCaptureDialog (I actively discourage this approach due to the brittle nature of the code which could stop working with a new ROM update etc).
The main problem with the existing CameraCapture code sample is that it does not provide a live preview of the video or still image being captured. However by altering the DirectShow “filter graph” and some of the surrounding application logic, it should be possible to add a live preview stream that renders to a specified region of the screen.
If you have access to the MEDC 2007 conference CD it would be helpful to view the “ECE310 – The Windows® Embedded CE 6.0 MDD/PDD Camera Driver Model” presentation. Although it discusses a newer camera device model not yet available on the Windows Mobile platform, I found the presentation useful in learning how the existing version works, since the presentation discussed the benefits of the new driver model by comparing it to the older one.
A couple of things to be aware of while investigating the use of DirectShow capture graphs:
- It could be significantly more complex than using the CameraCaptureDialog or SHCaptureDialog APIs depending upon your experience with COM based APIs.
- Across a range of devices you may have slightly inconsistent behaviour. For example some devices return images that are upside down and need to be manually flipped to be viewed correctly on the LCD. The Windows Mobile Test Kit tested if a device had implemented the API correctly, but didn’t test the “correctness” of the images it generated. Apparently this issue has been improved so that newer Windows Mobile devices should more consistantly implement this API.
Hopefully this provides you with some guidance Stefan and thanks for contacting me. One of the reasons I started this blog was to connect with the development community, so it was great to hear from you.
How much interest is there for a custom control that could be used within a .NET Compact Framework application to perform the kind of tasks Stefan is after with a few lines of managed code?