Camera.cs
上传用户:chengzheng
上传日期:2013-08-05
资源大小:38k
文件大小:11k
- using System;
- using OpenNETCF;
- using OpenNETCF.Diagnostics;
- using OpenNETCF.Win32;
- using Microsoft.WindowsCE.Forms;
- using System.Windows.Forms;
- using System.Runtime.InteropServices;
- namespace Cowburn.Imaging
- {
- #region Enums
- /// <summary>
- /// Describes the action carried out by the camera indicating whether
- /// the camera will return a file path string or a byte array containing
- /// the image data.
- /// </summary>
- public enum ReturnType : int
- {
- /// <summary>
- /// The camera captured an image to a file
- /// </summary>
- CaptureToFile = 48000,
- /// <summary>
- /// The camera is returning a byte array containing the image.
- /// </summary>
- ImageData = 48001,
- }
- /// <summary>
- /// Describes the action to be carried out by the camera indicating whether
- /// the camera should return a file path string or a byte array containing
- /// the image data.
- /// </summary>
- public enum RequestType : int
- {
- /// <summary>
- /// Request that the camera return a path to a capture file.
- /// </summary>
- CaptureToFile = 47000,
- /// <summary>
- /// Request that the camera return a byte array containing
- /// the image data
- /// </summary>
- ImageData = 47001,
- }
- #endregion
- /// <summary>
- /// Provides a mechanism for interoperating with the
- /// in-device HTC camera
- /// </summary>
- public class HtcCamera
- {
- #region Static Helpers
- /// <summary>
- /// Reads the path for the camera software from the registry.
- /// </summary>
- /// <param name="path">The path to the camera.</param>
- /// <returns>True: the path to the camera software was read successfully; else false</returns>
- public static bool GetCameraPath(ref string path)
- {
- bool b = false;
- // Read the path to the camera software from the Registry
- RegistryKey reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\IA Style\IPC\Camera");
- try
- {
- path = reg.GetValue("Path").ToString();
- b = true;
- }
- finally
- {
- if(reg != null)
- reg.Close();
- }
- return b;
- }
- /// <summary>
- /// Determines whether the camera software is installed.
- /// </summary>
- /// <param name="path">Path to the camera software.</param>
- /// <returns>True: if the software is installed; else false</returns>
- public static bool IsCameraInstalled(string path)
- {
- if(path == "" || path == string.Empty)
- throw new ArgumentException("szPath cannot be an empty string");
- return System.IO.File.Exists(path);
- }
- #endregion
- /// <summary>
- /// Occurs when the camera has (successfully or unsuccessfully)
- /// completed capture.
- /// </summary>
- public event CameraEventHandler CaptureCompleted;
- #region Fields
- private const int WM_COPYDATA = 0x4a;
- private CameraConfiguration _camConfig = null;
- private CallbackWnd cbWnd = null;
- internal CopyData _data = null;
- internal CaptureType _captureType;
- internal Orientation _orientation;
- internal Process _camera = null;
- #endregion
- #region Properties
- /// <summary>
- /// Get/Set the CaptureMode for the camera in this session.
- /// </summary>
- public CaptureMode CaptureMode
- {
- get { return _camConfig.CaptureMode; }
- set
- {
- _camConfig.CaptureMode = value;
- // Set the FileType to the correct type based on the
- // CaptureMode that has been set.
- switch(value)
- {
- case CaptureMode.Video:
- _camConfig.FileType = FileType.AVI;
- break;
- case CaptureMode.Image:
- _camConfig.FileType = FileType.JPEG;
- break;
- default:
- break;
- }
- }
- }
- /// <summary>
- /// Get/Set the FileType for the capture session.
- /// This can be ignored if CaptureMode is set.
- /// </summary>
- public FileType FileType
- {
- get { return _camConfig.FileType; }
- set { _camConfig.FileType = value; }
- }
-
- /// <summary>
- /// Get/Set the capture resolution.
- /// </summary>
- public Resolution Resolution
- {
- get { return _camConfig.Resolution; }
- set { _camConfig.Resolution = value; }
- }
- /// <summary>
- /// Get/Set the type of capture to perform
- /// (i.e. to file or to byte array)
- /// </summary>
- public CaptureType CaptureType
- {
- get { return _captureType; }
- set { _captureType = value; }
- }
- /// <summary>
- /// Get/Set the image orientation
- /// </summary>
- public Orientation Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the HtcCamera class.
- /// </summary>
- public HtcCamera()
- {
- cbWnd = new CallbackWnd(this);
- _camConfig = new CameraConfiguration(cbWnd.Hwnd);
- }
- /// <summary>
- /// Instruct the camera to capture an image/video clip.
- /// </summary>
- /// <param name="saveFolder">The folder to save captures into.</param>
- public void Capture(string saveFolder)
- {
- Capture(saveFolder, CaptureType.File);
- }
- /// <summary>
- /// Instruct the camera to capture an image/video clip.
- /// </summary>
- /// <param name="saveFolder">The folder to save captures into.</param>
- /// <param name="captureType">The type of capture to perform (file or data).</param>
- public void Capture(string saveFolder, CaptureType captureType)
- {
- string _path = string.Empty;
- if(GetCameraPath(ref _path) && IsCameraInstalled(_path))
- {
- if(saveFolder.Length > 260)
- throw new ArgumentOutOfRangeException("The max length of saveFolder is 260 characters");
- // Launch the camera software
- IntPtr hwndCamWiz = GetCameraWizardWnd(_path);
- if(hwndCamWiz != IntPtr.Zero)
- {
- // Set the configuration properties for the camera
- _camConfig.SaveFolder = saveFolder;
- _camConfig.CaptureType = _captureType = captureType;
- _camConfig.Orientation = _orientation;
- // Instruct the software to make a capture over IPC.
- _data = new CopyData();
- _data.dwData = 47000;
- _data.cbData = 548;
- _data.lpData = _camConfig.ToPointer();
- Win32Window.SendMessage(hwndCamWiz, WM_COPYDATA, 0, _data.Handle);
- }
- }
- }
- #region Instance Helpers
- private IntPtr GetCameraWizardWnd(string path)
- {
- int i=0;
- // Is the camera software running?
- IntPtr hAgent = Win32Window.FindWindow("IACW_AGENT", null);
- if(hAgent == IntPtr.Zero)
- {
- // Not at this point, so launch the software
- _camera = Process.Start(path);
- hAgent = Win32Window.FindWindow("IACW_AGENT",null);
- while((hAgent == IntPtr.Zero) && i < 50)
- {
- // Keep checking at 50ms intervals until the software is active
- System.Threading.Thread.Sleep(50);
- hAgent = Win32Window.FindWindow("IACW_AGENT",null);
- i++;
- }
- }
-
- // Have we reached our retry limit?
- if(i==50)
- {
- // Yes, so notify the user the launch failed
- MessageBox.Show("Failed to invoke the Camera Wizard, please try again or make sure IA Camera Wizard is already installed properly.",
- "Error",
- MessageBoxButtons.OK,
- MessageBoxIcon.Asterisk,
- MessageBoxDefaultButton.Button1
- );
- hAgent = IntPtr.Zero;
- }
- return hAgent;
- }
- #endregion
- #region CallbackWnd
- internal class CallbackWnd : MessageWindow
- {
- private HtcCamera _parent = null;
- private const int WM_COPYDATA = 0x4a;
- /// <summary>
- /// Initializes an instance of the CallbackWnd
- /// </summary>
- /// <param name="parent">A reference to the parent class that created this instance.</param>
- public CallbackWnd(HtcCamera parent)
- {
- _parent = parent;
- }
- protected override void WndProc(ref Message m)
- {
- switch(m.Msg)
- {
- case WM_COPYDATA:
- string path = string.Empty;
-
- // Marshal the CopyData and CaptureData structs out of unmanaged memory
- CopyData cd = (CopyData)Marshal.PtrToStructure(m.LParam, typeof(CopyData));
- CaptureData rd = (CaptureData)Marshal.PtrToStructure(cd.lpData, typeof(CaptureData));
- // CopyData.dwData should ALWAYS be 48000 since we're capturing images/video
- if(cd.dwData == (int)ReturnType.CaptureToFile)
- {
- if(rd.ReturnCode == 0)
- {
- // If the user chose to capture the image to file...
- if(_parent.CaptureType == CaptureType.File)
- {
- int cbReturnCap = (10 * Marshal.SystemDefaultCharSize); // sizeof(CaptureData) = 20 bytes
- path = Marshal.PtrToStringUni(new IntPtr((int)cd.lpData + cbReturnCap), (cd.cbData - cbReturnCap) / Marshal.SystemDefaultCharSize).Trim(' ');
- // Raise the CaptureCompleted event and pass in the data from the camera
- if(_parent.CaptureCompleted != null)
- _parent.CaptureCompleted(this, new CameraEventArgs(path, rd.Width, rd.Height));
- }
- // If the user chose to capture to a byte array
- else if(_parent.CaptureType == CaptureType.Data)
- {
- // Save data to file
- byte[] img = new byte[rd.cbData];
- Marshal.Copy(new IntPtr((int)cd.lpData + 20),img,0,rd.cbData);
- // Raise the CaptureCompleted event and pass in the data from the camera
- if(_parent.CaptureCompleted != null)
- _parent.CaptureCompleted(this, new CameraEventArgs(img, rd.Width, rd.Height));
- }
- }
- else if(rd.ReturnCode == 1)
- {
- // User cancelled the capture.
- MessageBox.Show("Capture cancelled by user.","Information",
- MessageBoxButtons.OK,
- MessageBoxIcon.Asterisk,
- MessageBoxDefaultButton.Button1
- );
- }
- else
- {
- // Another type of error occurred. This is likely to be due to the configuration
- // options set by the user.
- MessageBox.Show("Please check the options you have configured for the camera.","Error",
- MessageBoxButtons.OK,
- MessageBoxIcon.Exclamation,
- MessageBoxDefaultButton.Button1
- );
- }
- }
- // Clean up the COPYDATASTRUCT memory
- if(_parent._data != null)
- _parent._data.Dispose();
- // Tidying up on the HTC Himalaya seems to cause lock-ups
- // if you kill the process and then try to launch it again
- // later. So, only kill if we're on a Smartphone.
- if(EnvironmentEx.PlatformName == "SmartPhone")
- {
- if(_parent._camera != null)
- {
- _parent._camera.Kill();
- _parent._camera.Dispose();
- }
- }
- else
- {
- if(_parent._camera != null)
- {
- _parent._camera.Dispose();
- }
- }
- break;
- default:
- base.WndProc(ref m);
- break;
- }
- }
- }
- #endregion
- }
- }