EmbeddedImageCapture.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. using System;
  2. using System.IO;
  3. using InABox.Core;
  4. using Plugin.Media;
  5. using Xamarin.CommunityToolkit.Core;
  6. using Xamarin.CommunityToolkit.UI.Views;
  7. using Xamarin.Forms;
  8. using XF.Material.Forms.UI.Dialogs;
  9. namespace comal.timesheets
  10. {
  11. class EmbeddedImageCapture : Grid
  12. {
  13. public Button CameraButton = new Button();
  14. public Button LibraryButton = new Button();
  15. public Label CameraLabel = new Label();
  16. public Label LibraryLabel = new Label();
  17. public Document Document;
  18. public Image Image { get; set; }
  19. bool firstLoad;
  20. bool disableLibrary;
  21. bool isVideo;
  22. public byte[] bytes;
  23. public Plugin.Media.Abstractions.VideoQuality VideoQuality {get; set;}
  24. public TimeSpan VideoLength { get; set; }
  25. public EmbeddedImageCapture(bool disablelibrary = false, bool isvideo = false)
  26. {
  27. VerticalOptions = LayoutOptions.Center;
  28. firstLoad = true;
  29. Document = new Document();
  30. Image = new Image();
  31. disableLibrary = disablelibrary;
  32. isVideo = isvideo;
  33. AddColumnsAndRows();
  34. AddButtons();
  35. }
  36. private void AddColumnsAndRows()
  37. {
  38. new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };
  39. new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };
  40. RowDefinition row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) };
  41. RowDefinition row1 = new RowDefinition() { Height = new GridLength(5, GridUnitType.Star) };
  42. RowDefinition row2 = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };
  43. RowDefinitions.Add(row);
  44. RowDefinitions.Add(row1);
  45. RowDefinitions.Add(row2);
  46. if (isVideo)
  47. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Absolute) });
  48. }
  49. private void AddButtons()
  50. {
  51. if (firstLoad)
  52. {
  53. CameraButton.Clicked += CameraButton_Clicked;
  54. CameraButton.ImageSource = "cameraicon.png";
  55. CameraButton.Margin = 5;
  56. CameraButton.Padding = 2;
  57. SetColumn(CameraButton, 0);
  58. SetRow(CameraButton, 1);
  59. CameraButton.BackgroundColor = Color.FromHex("#15C7C1");
  60. CameraButton.HeightRequest = 90;
  61. CameraButton.WidthRequest = 90;
  62. CameraButton.CornerRadius = 15;
  63. CameraButton.HorizontalOptions = LayoutOptions.Center;
  64. CameraButton.VerticalOptions = LayoutOptions.Center;
  65. //CameraButton.BorderWidth = 1;
  66. //CameraButton.BorderColor = Color.Orange;
  67. LibraryButton.Clicked += LibraryButton_Clicked;
  68. LibraryButton.ImageSource = "photolibraryicon.png";
  69. if (Device.RuntimePlatform.Equals(Device.iOS))
  70. { LibraryButton.ImageSource = "photo.png"; }
  71. LibraryButton.Margin = 5;
  72. LibraryButton.Padding = 2;
  73. SetRow(LibraryButton, 1);
  74. SetColumn(LibraryButton, 1);
  75. LibraryButton.BackgroundColor = Color.FromHex("#15C7C1");
  76. LibraryButton.HeightRequest = 90;
  77. LibraryButton.WidthRequest = 90;
  78. LibraryButton.CornerRadius = 15;
  79. LibraryButton.HorizontalOptions = LayoutOptions.Center;
  80. LibraryButton.VerticalOptions = LayoutOptions.Center;
  81. if (disableLibrary)
  82. LibraryButton.IsEnabled = false;
  83. //LibraryButton.BorderWidth = 1;
  84. //LibraryButton.BorderColor = Color.Orange;
  85. CameraLabel.Text = "Camera";
  86. SetRow(CameraLabel, 2);
  87. SetColumn(CameraLabel, 0);
  88. CameraLabel.HorizontalOptions = LayoutOptions.Center;
  89. CameraLabel.HorizontalTextAlignment = TextAlignment.Center;
  90. CameraLabel.FontAttributes = FontAttributes.Bold;
  91. CameraLabel.FontSize = Device.GetNamedSize(NamedSize.Medium, CameraLabel);
  92. LibraryLabel.Text = "Library";
  93. SetRow(LibraryLabel, 2);
  94. SetColumn(LibraryLabel, 1);
  95. LibraryLabel.HorizontalOptions = LayoutOptions.Center;
  96. LibraryLabel.HorizontalTextAlignment = TextAlignment.Center;
  97. LibraryLabel.FontAttributes = FontAttributes.Bold;
  98. LibraryLabel.FontSize = Device.GetNamedSize(NamedSize.Medium, LibraryLabel);
  99. }
  100. Children.Add(CameraButton);
  101. Children.Add(LibraryButton);
  102. Children.Add(CameraLabel);
  103. Children.Add(LibraryLabel);
  104. if (isVideo)
  105. {
  106. var lbl = new Label { Text = "Take Video", FontAttributes = FontAttributes.Bold, FontSize = 24 };
  107. lbl.HorizontalOptions = LayoutOptions.Center;
  108. lbl.VerticalOptions = LayoutOptions.Center;
  109. SetRow(lbl, 3);
  110. SetColumn(lbl, 0);
  111. SetColumnSpan(lbl, 2);
  112. Children.Add(lbl);
  113. }
  114. firstLoad = false;
  115. }
  116. private void CameraButton_Clicked(object sender, EventArgs e)
  117. {
  118. if (isVideo)
  119. OpenVideoCamera();
  120. else
  121. OpenCamera();
  122. }
  123. private void LibraryButton_Clicked(object sender, EventArgs e)
  124. {
  125. if (isVideo)
  126. OpenVideoLibrary();
  127. else
  128. OpenLibrary();
  129. }
  130. private async void OpenVideoLibrary()
  131. {
  132. try
  133. {
  134. await CrossMedia.Current.Initialize();
  135. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
  136. {
  137. return;
  138. }
  139. var file = await CrossMedia.Current.PickVideoAsync();
  140. if (file == null)
  141. return;
  142. AddVideo(file);
  143. }
  144. catch { }
  145. }
  146. private async void OpenVideoCamera()
  147. {
  148. try
  149. {
  150. await CrossMedia.Current.Initialize();
  151. if (CrossMedia.Current.IsCameraAvailable && CrossMedia.Current.IsTakeVideoSupported)
  152. {
  153. var file = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions()
  154. {
  155. CompressionQuality = 15,
  156. PhotoSize = Plugin.Media.Abstractions.PhotoSize.MaxWidthHeight,
  157. Quality = Plugin.Media.Abstractions.VideoQuality.Low,
  158. DesiredLength = new TimeSpan(0, 0, 20),
  159. RotateImage = false
  160. });
  161. if (file == null)
  162. return;
  163. AddVideo(file);
  164. }
  165. }
  166. catch
  167. {
  168. return;
  169. }
  170. }
  171. private async void OpenLibrary()
  172. {
  173. try
  174. {
  175. await CrossMedia.Current.Initialize();
  176. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  177. {
  178. return;
  179. }
  180. var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions()
  181. {
  182. CompressionQuality = 15,
  183. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full,
  184. });
  185. if (file == null)
  186. return;
  187. AddPhoto(file);
  188. }
  189. catch
  190. {
  191. return;
  192. }
  193. }
  194. private async void OpenCamera()
  195. {
  196. try
  197. {
  198. await CrossMedia.Current.Initialize();
  199. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  200. {
  201. return;
  202. }
  203. String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now);
  204. var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
  205. {
  206. Name = filename,
  207. CompressionQuality = 15,
  208. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full,
  209. SaveMetaData = false
  210. });
  211. if (file == null)
  212. return;
  213. AddPhoto(file);
  214. }
  215. catch(Exception e)
  216. {
  217. }
  218. }
  219. private async void AddVideo(Plugin.Media.Abstractions.MediaFile file)
  220. {
  221. try
  222. {
  223. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Video"))
  224. {
  225. var memoryStream = new MemoryStream();
  226. //if (Device.RuntimePlatform.Equals(Device.Android))
  227. // file.GetStream().CopyTo(memoryStream);
  228. //else if (Device.RuntimePlatform.Equals(Device.iOS))
  229. file.GetStreamWithImageRotatedForExternalStorage().CopyTo(memoryStream);
  230. var data = memoryStream.ToArray();
  231. bytes = data;
  232. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  233. MediaElement element = new MediaElement();
  234. element.HorizontalOptions = LayoutOptions.Center;
  235. element.VerticalOptions = LayoutOptions.Center;
  236. element.ShowsPlaybackControls = true;
  237. element.Aspect = Aspect.Fill;
  238. element.HeightRequest = 800;
  239. element.WidthRequest = 400;
  240. element.AutoPlay = false;
  241. element.Margin = 5;
  242. element.Source = file.Path;
  243. Device.BeginInvokeOnMainThread(() =>
  244. {
  245. Children.Clear();
  246. RowDefinitions.Clear();
  247. ColumnDefinitions.Clear();
  248. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(35, GridUnitType.Absolute) });
  249. RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
  250. ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
  251. Image img = new Image { Source = "closee.png" };
  252. img.GestureRecognizers.Add(new TapGestureRecognizer
  253. {
  254. Command = new Command(OnVideoTap),
  255. CommandParameter = data,
  256. NumberOfTapsRequired = 1
  257. });
  258. img.HorizontalOptions = LayoutOptions.Center;
  259. img.VerticalOptions = LayoutOptions.Center;
  260. img.HeightRequest = 35;
  261. img.WidthRequest = 35;
  262. img.Margin = new Thickness(5, 5, 5, 0);
  263. SetRow(img, 0);
  264. SetColumn(img, 0);
  265. SetRow(element, 1);
  266. SetColumn(element, 0);
  267. Padding = new Thickness(0);
  268. Children.Add(img);
  269. Children.Add(element);
  270. HorizontalOptions = LayoutOptions.CenterAndExpand;
  271. ForceLayout();
  272. });
  273. }
  274. }
  275. catch
  276. { }
  277. }
  278. private void OnVideoTap(object obj)
  279. {
  280. bytes = new byte[] { };
  281. RowDefinitions.Clear();
  282. ColumnDefinitions.Clear();
  283. Viewer_OnDeleteSelected();
  284. }
  285. private async void AddPhoto(Plugin.Media.Abstractions.MediaFile file)
  286. {
  287. try
  288. {
  289. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  290. {
  291. var memoryStream = new MemoryStream();
  292. if (Device.RuntimePlatform.Equals(Device.Android))
  293. file.GetStream().CopyTo(memoryStream);
  294. else if (Device.RuntimePlatform.Equals(Device.iOS))
  295. file.GetStreamWithImageRotatedForExternalStorage().CopyTo(memoryStream);
  296. var data = memoryStream.ToArray();
  297. DataToImage(data);
  298. }
  299. }
  300. catch
  301. { }
  302. }
  303. public void DataToImage(byte[] data)
  304. {
  305. try
  306. {
  307. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  308. Image = new Image();
  309. Image.HeightRequest = 200;
  310. Image.WidthRequest = 200;
  311. Image.Aspect = Aspect.AspectFit;
  312. Image.VerticalOptions = LayoutOptions.FillAndExpand;
  313. Image.HorizontalOptions = LayoutOptions.FillAndExpand;
  314. Image.Source = src;
  315. Image.GestureRecognizers.Add(new TapGestureRecognizer
  316. {
  317. Command = new Command(OnTap),
  318. CommandParameter = src,
  319. NumberOfTapsRequired = 1
  320. });
  321. if (Image != null)
  322. {
  323. Device.BeginInvokeOnMainThread(() =>
  324. {
  325. Children.Clear();
  326. RowDefinitions.Clear();
  327. ColumnDefinitions.Clear();
  328. Children.Add(Image);
  329. });
  330. }
  331. }
  332. catch
  333. { }
  334. }
  335. private void OnTap(object obj)
  336. {
  337. ImageViewerEditor imageViewEditor = new ImageViewerEditor(obj as ImageSource, true);
  338. imageViewEditor.OnDeleteSelected += Viewer_OnDeleteSelected;
  339. imageViewEditor.OnSaveSelected += ImageViewEditor_OnSaveSelected;
  340. Navigation.PushAsync(imageViewEditor);
  341. }
  342. private void ImageViewEditor_OnSaveSelected(byte[] array)
  343. {
  344. DataToImage(array);
  345. }
  346. private void Viewer_OnDeleteSelected()
  347. {
  348. Document = new Document();
  349. Image = new Image();
  350. Image.Source = null;
  351. Children.Clear();
  352. AddColumnsAndRows();
  353. AddButtons();
  354. }
  355. public void ClearItems()
  356. {
  357. Image = new Image();
  358. Image.Source = null;
  359. Children.Clear();
  360. }
  361. }
  362. }