PageRenderTime 24ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/windows8/lib/WinRTBarcodeReader/WinRTBarcodeReader/Reader.cs

https://gitlab.com/taveek/cordova-plugin-barcodescanner
C# | 197 lines | 107 code | 28 blank | 62 comment | 4 complexity | 7fd44542223c8a2e112cb14cecd19c9b MD5 | raw file
  1. /*
  2. * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  9. */
  10. namespace WinRTBarcodeReader
  11. {
  12. using System;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using Windows.Foundation;
  16. using Windows.Media.Capture;
  17. using Windows.Media.MediaProperties;
  18. using Windows.Storage.Streams;
  19. using ZXing;
  20. /// <summary>
  21. /// Defines the Reader type, that perform barcode search asynchronously.
  22. /// </summary>
  23. public sealed class Reader
  24. {
  25. #region Private fields
  26. /// <summary>
  27. /// MediaCapture instance, used for barcode search.
  28. /// </summary>
  29. private readonly MediaCapture capture;
  30. /// <summary>
  31. /// Encoding properties for mediaCapture object.
  32. /// </summary>
  33. private readonly ImageEncodingProperties encodingProps;
  34. /// <summary>
  35. /// Image stream for MediaCapture content.
  36. /// </summary>
  37. private InMemoryRandomAccessStream imageStream;
  38. /// <summary>
  39. /// Data reader, used to create bitmap array.
  40. /// </summary>
  41. private DataReader datareader;
  42. /// <summary>
  43. /// Flag that indicates successful barcode search.
  44. /// </summary>
  45. private bool barcodeFound;
  46. /// <summary>
  47. /// The cancel search flag.
  48. /// </summary>
  49. private CancellationTokenSource cancelSearch;
  50. #endregion
  51. #region Constructor
  52. /// <summary>
  53. /// Initializes a new instance of the <see cref="Reader" /> class.
  54. /// </summary>
  55. /// <param name="capture">MediaCapture instance.</param>
  56. /// <param name="width">Capture frame width.</param>
  57. /// <param name="height">Capture frame height.</param>
  58. public Reader(MediaCapture capture, uint width, uint height)
  59. {
  60. this.capture = capture;
  61. this.encodingProps = new ImageEncodingProperties { Subtype = "BMP", Width = width, Height = height};
  62. this.barcodeFound = false;
  63. this.cancelSearch = new CancellationTokenSource();
  64. }
  65. #endregion
  66. #region Public methods
  67. /// <summary>
  68. /// Perform async MediaCapture analysis and searches for barcode.
  69. /// </summary>
  70. /// <returns>IAsyncOperation object</returns>
  71. public IAsyncOperation<Result> ReadCode()
  72. {
  73. return this.Read().AsAsyncOperation();
  74. }
  75. /// <summary>
  76. /// Send signal to stop barcode search.
  77. /// </summary>
  78. public void Stop()
  79. {
  80. this.cancelSearch.Cancel();
  81. }
  82. #endregion
  83. #region Private methods
  84. /// <summary>
  85. /// Perform async MediaCapture analysis and searches for barcode.
  86. /// </summary>
  87. /// <returns>Task object</returns>
  88. private async Task<Result> Read()
  89. {
  90. Result result = null;
  91. while (!this.barcodeFound)
  92. {
  93. try
  94. {
  95. result = await this.GetCameraImage(this.cancelSearch.Token);
  96. }
  97. catch (OperationCanceledException)
  98. {
  99. result = null;
  100. }
  101. }
  102. return result;
  103. }
  104. /// <summary>
  105. /// Perform image capture from mediaCapture object
  106. /// </summary>
  107. /// <param name="cancelToken">
  108. /// The cancel Token.
  109. /// </param>
  110. /// <returns>
  111. /// Decoded barcode string.
  112. /// </returns>
  113. private async Task<Result> GetCameraImage(CancellationToken cancelToken)
  114. {
  115. Result result = null;
  116. await Task.Run(
  117. async () =>
  118. {
  119. this.imageStream = new InMemoryRandomAccessStream();
  120. await this.capture.CapturePhotoToStreamAsync(this.encodingProps, this.imageStream);
  121. await this.imageStream.FlushAsync();
  122. this.datareader = new DataReader(this.imageStream);
  123. await this.datareader.LoadAsync((uint)this.imageStream.Size);
  124. var bitmap = new byte[this.encodingProps.Width * this.encodingProps.Height * 4];
  125. uint index = 0;
  126. while (this.datareader.UnconsumedBufferLength > 0)
  127. {
  128. bitmap[index] = datareader.ReadByte();
  129. index++;
  130. }
  131. result = await this.DecodeBitmap(bitmap);
  132. if (result != null)
  133. {
  134. this.barcodeFound = true;
  135. }
  136. },
  137. cancelToken).ConfigureAwait(false);
  138. return result;
  139. }
  140. /// <summary>
  141. /// Searches the bitmap for barcode.
  142. /// </summary>
  143. /// <param name="bitmap">Array of bytes, represents bitmap</param>
  144. /// <param name="format">Bitmap format, default is BGRA32</param>
  145. /// <returns>String, encoded with barcode or empty string if barcode not found</returns>
  146. private async Task<Result> DecodeBitmap(byte[] bitmap, BitmapFormat format = BitmapFormat.BGRA32)
  147. {
  148. Result result = null;
  149. try
  150. {
  151. await Task.Run(
  152. () =>
  153. {
  154. var c = new BarcodeReader();
  155. result = c.Decode(
  156. bitmap,
  157. (int)this.encodingProps.Width,
  158. (int)this.encodingProps.Height,
  159. format);
  160. }).ConfigureAwait(false);
  161. }
  162. catch (Exception)
  163. {
  164. }
  165. return result;
  166. }
  167. #endregion
  168. }
  169. }