UWPアプリケーションでのバーコードとQRコードの認識







最も人気のあるバーコード認識ライブラリがZXing(「Zebra Crossing」)であると言っても、アメリカを発見することはできません。 サポートされている形式のリストは非常に印象的で、EAN-8とEAN-13、QRコード、UPC-AとUPC-E、Code 39、Code 93、Code 128などが含まれます。



WinRT用のポートがあります。これは、ライブラリをユニバーサルWindowsプラットフォームで使用できることを意味します。



バーコード認識用のPCLはZXing.Netと呼ばれ、この名前は.Netアプリケーションでもこのライブラリを使用できることを示唆しているようです。



すぐに注意を払わなければならなかったもの。 簡単な写真を撮る場合、通常は気にせず、写真を撮るだけです。 画像を処理する場合、画質が最高であることが必要です。 したがって、カメラを初期化するときは、可能な最大解像度を設定する必要があります。 これを行うには、 サンプルコードに似たコードを使用します。 カメラ解像度のサンプル



さらに、デバイスに前面カメラまたは背面カメラがあるかどうかを判断する必要があります。 これは簡単です:



var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); DeviceInformation frontCamera = null; DeviceInformation rearCamera = null; foreach (var device in devices) { switch (device.EnclosureLocation.Panel) { case Windows.Devices.Enumeration.Panel.Front: frontCamera = device; break; case Windows.Devices.Enumeration.Panel.Back: rearCamera = device; break; } }
      
      





その後、メディアキャプチャを初期化できます。



  if (rearCamera != null) { await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings { VideoDeviceId = rearCamera.Id }); }
      
      





許可の設定は次のとおりです。



  public async Task SetResolution() { System.Collections.Generic.IReadOnlyList<IMediaEncodingProperties> res; res = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo); uint maxResolution = 0; int indexMaxResolution = 0; if (res.Count >= 1) { for (int i = 0; i < res.Count; i++) { VideoEncodingProperties vp = (VideoEncodingProperties)res[i]; if (vp.Width > maxResolution) { indexMaxResolution = i; maxResolution = vp.Width; } } await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, res[indexMaxResolution]); } }
      
      





画像のキャプチャと認識は次のように行われます。



 IRandomAccessStream fileStream = new InMemoryRandomAccessStream(); await mediaCapture.CapturePhotoToStreamAsync(Windows.Media.MediaProperties.ImageEncodingProperties.CreateBmp(), fileStream); string res = await BarcodeDecoder.DecodeStreamToBarcode(fileStream);
      
      





ストリームを認識するには、 Mike Taultyから取得したBarcodeDecoderクラスを使用します



クラスコードはスポイラーの下に隠されています
 internal static class BarcodeDecoder { static BarcodeReader barcodeReader; static BarcodeDecoder() { barcodeReader = new ZXing.BarcodeReader(); barcodeReader.Options.PureBarcode = false; barcodeReader.Options.Hints.Add(DecodeHintType.TRY_HARDER, true); barcodeReader.Options.PossibleFormats = new BarcodeFormat[] { BarcodeFormat.QR_CODE,BarcodeFormat.All_1D }; barcodeReader.Options.TryHarder = true; barcodeReader.AutoRotate = true; } public async static Task<string> DecodeStreamToBarcode(IRandomAccessStream photoStream) { BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(photoStream); BitmapTransform emptyBitmapTransform = new BitmapTransform(); PixelDataProvider pixelDataProvider = await bitmapDecoder.GetPixelDataAsync( BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, emptyBitmapTransform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage); var zxingResult = barcodeReader.Decode(pixelDataProvider.DetachPixelData(), (int)bitmapDecoder.PixelWidth, (int)bitmapDecoder.PixelHeight, BitmapFormat.RGBA32); string res = ""; if (!String.IsNullOrEmpty(zxingResult?.Text)) res = zxingResult?.Text; return res; } }
      
      







このクラスは、QR_CODEおよびAll_1Dバーコードを認識します。 この場合、All_1Dには、UPC-A、UPC-E、EAN-8、およびEAN-13の形式が含まれます。 他の形式を追加することもできます。 使用するデコーダーが次の形式をサポートしているとします:UPC-A、UPC-E、EAN-8、EAN-13、Code 39、Code 93、Code 128、ITF、Codabar、MSI、RSS-14(すべてのオプション) 、QRコード、データマトリックス、AztecおよびPDF-417



この認識方法は、既存の画像に適しています。 カメラを使用する場合は、認識できる画像が得られるまで多くの写真を撮る必要があります。 言い換えれば、最初のパンケーキはゴツゴツしたものであることが判明しましたが、いくつかの有用な経験が得られました。



その場でコード認識



集中的な検索の結果、次のVideoScanZXingWinRTリポジトリが見つかりましたが、これが基礎となりました。 画像キャプチャはプレビューモードから取得されます。



ここで、少し遅れて、焦点合わせ機能のないカメラでは通常のマクロ撮影ができないという認識に至りました。 理論的には、オートフォーカスのないカメラを搭載した携帯電話でバーコードをスキャンできますが、その可能性はわずかです。 自分で試すことができます。 焦点を合わせたカメラはオートフォーカスをサポートでき、手動モードで焦点を合わせることができます。 手動モードでは、3秒ごとに自動タイマータイマーを実行しました。



さらに、バックライトがオフになり、グレアが発生して認識が妨げられました



  if (mediaCapture.VideoDeviceController.FlashControl.Supported) mediaCapture.VideoDeviceController.FlashControl.Auto = false;
      
      





余分な部分を削除して修正した結果、次のような例が得られました。



Barcode_Scanner_UWP



私は皆をプロジェクトに参加するように招待します。 私は改善と調整に喜んでいるでしょう。



プロジェクトで使用するには、C#コードビハインドとともにBarcodeScannerControl.xamlユーザーコントロールを追加する必要があります。 次に、呼び出し元のページのコード(この例ではMainPage.xaml)に、内部にユーザーコントロールを含むポップアップを追加します。



  <Popup x:Name="BarcodePopup" IsOpen="False" IsLightDismissEnabled="False"> <Grid> <local:BarcodeScannerControl x:Name="barcodecontrol" Width="{Binding ElementName=MainGrid,Path=ActualWidth}" Height="{Binding ElementName=MainGrid,Path=ActualHeight}"></local:BarcodeScannerControl> </Grid> </Popup>
      
      





この場合、ユーザーコントロールの幅と高さは、MainGridという名前のウィンドウコンテナー要素の寸法に関連付けられています。



C#コードに2つのメソッドを追加する必要があります。 1つはバーコード検索が成功した場合に呼び出され、2つ目はエラーが発生した場合に呼び出されます。 メソッドのシグネチャは、1つのパラメーターが文字列、2番目の例外のパラメーターであるようなものです。 例では、これらはvoid BarcodeFound(文字列バーコード)およびvoid OnError(例外e)です。



これで、ポップアップを開き、カメラから画像のプレビューを起動してバーコードをスキャンするメソッドを実行できます。



 BarcodePopup.IsOpen = true; await barcodecontrol.StartScan(BarcodeFound, OnError);
      
      





心に留めておくべきことの1つは、UWPアプリケーションのライフサイクルです。 この場合、アプリケーションが「一時停止」状態になった場合、カメラから画像を表示し、バーコードを検索してポップアップを閉じるプロセスを停止する必要があります。 つまり、次のコードを追加します。



  private async void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); await barcodecontrol.Cleanup(); BarcodePopup.IsOpen = false; deferral.Complete(); } protected override void OnNavigatedTo(NavigationEventArgs e) { Application.Current.Suspending += App_Suspending; } protected override void OnNavigatedFrom(NavigationEventArgs e) { Application.Current.Suspending -= App_Suspending; }
      
      





今、短所について。 1つマイナス-ZXing.Netライブラリは2年間更新されていません。 一方、バグなしで動作し、新しい関数を必要としない場合、おそらくそれは何も問題はありません。 このプロジェクトは非公式なので、開発者が空き時間があるときに作業を進めます。 古い学校のCodeplexのサイトは、生命の兆候を示しています 。 その上にソースコードがあります。 良いニュースは、ライブラリ自体の更新が近い将来に計画されていることです。つまり、プロジェクトは放棄されていません。



All Articles