Camera.cs
上传用户:chengzheng
上传日期:2013-08-05
资源大小:38k
文件大小:11k
源码类别:

Windows Mobile

开发平台:

C#

  1. using System;
  2. using OpenNETCF;
  3. using OpenNETCF.Diagnostics;
  4. using OpenNETCF.Win32;
  5. using Microsoft.WindowsCE.Forms;
  6. using System.Windows.Forms;
  7. using System.Runtime.InteropServices;
  8. namespace Cowburn.Imaging
  9. {
  10. #region Enums
  11. /// <summary>
  12. /// Describes the action carried out by the camera indicating whether 
  13. /// the camera will return a file path string or a byte array containing
  14. /// the image data.
  15. /// </summary>
  16. public enum ReturnType : int
  17. {
  18. /// <summary>
  19. /// The camera captured an image to a file
  20. /// </summary>
  21. CaptureToFile = 48000,
  22. /// <summary>
  23. /// The camera is returning a byte array containing the image.
  24. /// </summary>
  25. ImageData = 48001,
  26. }
  27. /// <summary>
  28. /// Describes the action to be carried out by the camera indicating whether 
  29. /// the camera should return a file path string or a byte array containing
  30. /// the image data.
  31. /// </summary>
  32. public enum RequestType : int
  33. {
  34. /// <summary>
  35. /// Request that the camera return a path to a capture file.
  36. /// </summary>
  37. CaptureToFile = 47000,
  38. /// <summary>
  39. /// Request that the camera return a byte array containing 
  40. /// the image data
  41. /// </summary>
  42. ImageData = 47001,
  43. }
  44. #endregion
  45. /// <summary>
  46. /// Provides a mechanism for interoperating with the 
  47. /// in-device HTC camera
  48. /// </summary>
  49. public class HtcCamera
  50. {
  51. #region Static Helpers
  52. /// <summary>
  53. /// Reads the path for the camera software from the registry.
  54. /// </summary>
  55. /// <param name="path">The path to the camera.</param>
  56. /// <returns>True: the path to the camera software was read successfully; else false</returns>
  57. public static bool GetCameraPath(ref string path)
  58. {
  59. bool b = false;
  60. // Read the path to the camera software from the Registry
  61. RegistryKey reg = Registry.LocalMachine.OpenSubKey("SOFTWARE\IA Style\IPC\Camera");
  62. try 
  63. {
  64. path = reg.GetValue("Path").ToString();
  65. b = true;
  66. }
  67. finally
  68. {
  69. if(reg != null)
  70. reg.Close();
  71. }
  72. return b;
  73. }
  74. /// <summary>
  75. /// Determines whether the camera software is installed.
  76. /// </summary>
  77. /// <param name="path">Path to the camera software.</param>
  78. /// <returns>True: if the software is installed; else false</returns>
  79. public static bool IsCameraInstalled(string path)
  80. {
  81. if(path == "" || path == string.Empty)
  82. throw new ArgumentException("szPath cannot be an empty string");
  83. return System.IO.File.Exists(path);
  84. }
  85. #endregion
  86. /// <summary>
  87. /// Occurs when the camera has (successfully or unsuccessfully) 
  88. /// completed capture.
  89. /// </summary>
  90. public event CameraEventHandler CaptureCompleted;
  91. #region Fields
  92. private const int WM_COPYDATA = 0x4a;
  93.    private CameraConfiguration _camConfig = null;
  94. private CallbackWnd cbWnd = null;
  95. internal CopyData _data = null;
  96. internal CaptureType _captureType;
  97. internal Orientation _orientation;
  98. internal Process _camera = null;
  99. #endregion 
  100. #region Properties
  101. /// <summary>
  102. /// Get/Set the CaptureMode for the camera in this session.
  103. /// </summary>
  104. public CaptureMode CaptureMode
  105. {
  106. get { return _camConfig.CaptureMode; }
  107. set 
  108. {
  109. _camConfig.CaptureMode = value; 
  110. // Set the FileType to the correct type based on the 
  111. // CaptureMode that has been set.
  112. switch(value)
  113. {
  114. case CaptureMode.Video:
  115. _camConfig.FileType = FileType.AVI;
  116. break;
  117. case CaptureMode.Image:
  118. _camConfig.FileType = FileType.JPEG;
  119. break;
  120. default:
  121. break;
  122. }
  123. }
  124. }
  125. /// <summary>
  126. /// Get/Set the FileType for the capture session.
  127. /// This can be ignored if CaptureMode is set.
  128. /// </summary>
  129. public FileType FileType
  130. {
  131. get { return _camConfig.FileType; }
  132. set { _camConfig.FileType = value; }
  133. }
  134. /// <summary>
  135. /// Get/Set the capture resolution.
  136. /// </summary>
  137. public Resolution Resolution
  138. {
  139. get { return _camConfig.Resolution; }
  140. set { _camConfig.Resolution = value; }
  141. }
  142. /// <summary>
  143. /// Get/Set the type of capture to perform 
  144. /// (i.e. to file or to byte array)
  145. /// </summary>
  146. public CaptureType CaptureType
  147. {
  148. get { return _captureType; }
  149. set { _captureType = value; }
  150. }
  151. /// <summary>
  152. /// Get/Set the image orientation
  153. /// </summary>
  154. public Orientation Orientation
  155. {
  156. get { return _orientation; }
  157. set { _orientation = value; }
  158. }
  159. #endregion 
  160. /// <summary>
  161. /// Initializes a new instance of the HtcCamera class.
  162. /// </summary>
  163. public HtcCamera()
  164. {
  165. cbWnd = new CallbackWnd(this);
  166. _camConfig = new CameraConfiguration(cbWnd.Hwnd);
  167. }
  168. /// <summary>
  169. /// Instruct the camera to capture an image/video clip.
  170. /// </summary>
  171. /// <param name="saveFolder">The folder to save captures into.</param>
  172. public void Capture(string saveFolder)
  173. {
  174. Capture(saveFolder, CaptureType.File);
  175. }
  176. /// <summary>
  177. /// Instruct the camera to capture an image/video clip.
  178. /// </summary>
  179. /// <param name="saveFolder">The folder to save captures into.</param>
  180. /// <param name="captureType">The type of capture to perform (file or data).</param>
  181. public void Capture(string saveFolder, CaptureType captureType)
  182. {
  183. string _path = string.Empty;
  184. if(GetCameraPath(ref _path) && IsCameraInstalled(_path))
  185. {
  186. if(saveFolder.Length > 260)
  187. throw new ArgumentOutOfRangeException("The max length of saveFolder is 260 characters");
  188. // Launch the camera software
  189. IntPtr hwndCamWiz = GetCameraWizardWnd(_path);
  190. if(hwndCamWiz != IntPtr.Zero)
  191. {
  192. // Set the configuration properties for the camera
  193. _camConfig.SaveFolder = saveFolder;
  194. _camConfig.CaptureType = _captureType = captureType;
  195. _camConfig.Orientation = _orientation;
  196. // Instruct the software to make a capture over IPC.
  197. _data = new CopyData();
  198. _data.dwData = 47000;
  199. _data.cbData = 548;
  200. _data.lpData = _camConfig.ToPointer();
  201. Win32Window.SendMessage(hwndCamWiz, WM_COPYDATA, 0, _data.Handle);
  202. }
  203. }
  204. }
  205. #region Instance Helpers
  206. private IntPtr GetCameraWizardWnd(string path)
  207. {
  208. int i=0;
  209. // Is the camera software running?
  210. IntPtr hAgent = Win32Window.FindWindow("IACW_AGENT", null);
  211. if(hAgent == IntPtr.Zero)
  212. {
  213. // Not at this point, so launch the software
  214. _camera = Process.Start(path);
  215. hAgent = Win32Window.FindWindow("IACW_AGENT",null);
  216. while((hAgent == IntPtr.Zero) && i < 50)
  217. {
  218. // Keep checking at 50ms intervals until the software is active
  219. System.Threading.Thread.Sleep(50);
  220. hAgent = Win32Window.FindWindow("IACW_AGENT",null);
  221. i++;
  222. }
  223. }
  224. // Have we reached our retry limit?
  225. if(i==50)
  226. {
  227. // Yes, so notify the user the launch failed
  228. MessageBox.Show("Failed to invoke the Camera Wizard, please try again or make sure IA Camera Wizard is already installed properly.",
  229. "Error",
  230. MessageBoxButtons.OK,
  231. MessageBoxIcon.Asterisk,
  232. MessageBoxDefaultButton.Button1
  233. );
  234. hAgent =  IntPtr.Zero;
  235. }
  236. return hAgent;
  237. }
  238. #endregion 
  239. #region CallbackWnd
  240. internal class CallbackWnd : MessageWindow
  241. {
  242. private HtcCamera _parent = null;
  243. private const int WM_COPYDATA = 0x4a;
  244. /// <summary>
  245. /// Initializes an instance of the CallbackWnd
  246. /// </summary>
  247. /// <param name="parent">A reference to the parent class that created this instance.</param>
  248. public CallbackWnd(HtcCamera parent)
  249. {
  250. _parent = parent;
  251. }
  252. protected override void WndProc(ref Message m)
  253. {
  254. switch(m.Msg)
  255. {
  256. case WM_COPYDATA:
  257. string path = string.Empty;
  258. // Marshal the CopyData and CaptureData structs out of unmanaged memory
  259. CopyData cd = (CopyData)Marshal.PtrToStructure(m.LParam, typeof(CopyData));
  260. CaptureData rd = (CaptureData)Marshal.PtrToStructure(cd.lpData, typeof(CaptureData));
  261. // CopyData.dwData should ALWAYS be 48000 since we're capturing images/video
  262. if(cd.dwData == (int)ReturnType.CaptureToFile)
  263. {
  264. if(rd.ReturnCode == 0)
  265. {
  266. // If the user chose to capture the image to file... 
  267. if(_parent.CaptureType == CaptureType.File)
  268. {
  269. int cbReturnCap = (10 * Marshal.SystemDefaultCharSize); // sizeof(CaptureData) = 20 bytes
  270. path = Marshal.PtrToStringUni(new IntPtr((int)cd.lpData + cbReturnCap), (cd.cbData - cbReturnCap) / Marshal.SystemDefaultCharSize).Trim('');
  271. // Raise the CaptureCompleted event and pass in the data from the camera
  272. if(_parent.CaptureCompleted != null)
  273. _parent.CaptureCompleted(this, new CameraEventArgs(path, rd.Width, rd.Height));
  274. }
  275. // If the user chose to capture to a byte array
  276. else if(_parent.CaptureType == CaptureType.Data)
  277. {
  278. // Save data to file 
  279. byte[] img = new byte[rd.cbData];
  280. Marshal.Copy(new IntPtr((int)cd.lpData + 20),img,0,rd.cbData);
  281. // Raise the CaptureCompleted event and pass in the data from the camera
  282. if(_parent.CaptureCompleted != null)
  283. _parent.CaptureCompleted(this, new CameraEventArgs(img, rd.Width, rd.Height));
  284. }
  285. }
  286. else if(rd.ReturnCode == 1)
  287. {
  288. // User cancelled the capture.
  289. MessageBox.Show("Capture cancelled by user.","Information",
  290. MessageBoxButtons.OK,
  291. MessageBoxIcon.Asterisk,
  292. MessageBoxDefaultButton.Button1
  293. );
  294. }
  295. else
  296. {
  297. // Another type of error occurred. This is likely to be due to the configuration 
  298. // options set by the user.
  299. MessageBox.Show("Please check the options you have configured for the camera.","Error",
  300. MessageBoxButtons.OK,
  301. MessageBoxIcon.Exclamation,
  302. MessageBoxDefaultButton.Button1
  303. );
  304. }
  305. }
  306. // Clean up the COPYDATASTRUCT memory
  307. if(_parent._data != null)
  308. _parent._data.Dispose();
  309. // Tidying up on the HTC Himalaya seems to cause lock-ups 
  310. // if you kill the process and then try to launch it again
  311. // later. So, only kill if we're on a Smartphone.
  312. if(EnvironmentEx.PlatformName == "SmartPhone")
  313. {
  314. if(_parent._camera != null)
  315. {
  316. _parent._camera.Kill();
  317. _parent._camera.Dispose();
  318. }
  319. }
  320. else
  321. {
  322. if(_parent._camera != null)
  323. {
  324. _parent._camera.Dispose();
  325. }
  326. }
  327. break;
  328. default: 
  329. base.WndProc(ref m);
  330. break;
  331. }
  332. }
  333. }
  334. #endregion
  335. }
  336. }