2016-12-02 10 views
0

저는 Windows 10 플랫폼의 Universal Windows App에서 작업하고 있습니다. 응용 프로그램은 바코드를 캡처하고 바코드와 함께 유용한 작업을 수행하기 위해 카메라를 사용해야합니다. 지금까지 바코드 캡처 및 변환 (ZXing 라이브러리 사용)과 관련하여 잘 작동합니다. 각 바코드에 대해 버튼을 한 번 클릭하여 바코드를 차례로 캡처 할 수 있습니다.내 유니버설 윈도우 앱의 카메라 손전등은 한 번만 작동합니다.

하지만 저조도에서도 작동해야합니다. 저 조명 상태에서 손전등 (또는 횃불)을 자동으로 켜도록 카메라에 요청하고 싶습니다. 나는 카메라가 어두운 곳에서 손전등 (또는 횃불)을 자동으로 켜는 것을 발견했다 전에 첫 사진을 찍는다. 어떻게 든 손전등은 첫 번째 사진 이후에 꺼집니다. 사용자가 내 앱의 동일한 페이지에 머물러있는 한 (그리고 환경이 어두우면) ON 상태를 유지하고 싶습니다. 이 문제를 해결하도록 도와주세요.

지금까지 MediaCapture.CapturePhotoToStorageFileAsync()가 손전등을 끄는 명령인지 확인할 수 있습니다.

다음은이 문제를 설명하는 작동 테스트 프로그램입니다.

그것은 테스트 응용 프로그램에서 MainPage.xaml을 프로그램 파일입니다 :

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Runtime.InteropServices.WindowsRuntime; 
using Windows.Foundation; 
using Windows.Foundation.Collections; 
using Windows.Graphics.Imaging;  // For BitmapDecoder. 
using Windows.Media.Capture;   // For MediaCapture. 
using Windows.Media.Devices;   // For FocusSettings, FocusMode, AutoFocusRange. 
using Windows.Media.MediaProperties; // For ImageEncodingProperties. 
using Windows.Media.Playback;   // For MediaPlayer.Volume. 
using Windows.Storage;     // For StorageFile. 
using Windows.Storage.Streams;   // For IRandomAccessStream. 
using Windows.UI.Popups;    // For MessageDialog(). 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Controls.Primitives; 
using Windows.UI.Xaml.Data; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Media.Imaging; // For WriteableBitmap. 
using Windows.UI.Xaml.Navigation; 
//using ZXing;       // For BarcodeFormat. 

// The Blank Page item template is documented 
// at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 

namespace TestApp 
    { 
    /// <summary> 
    /// An empty page that can be used on its own or navigated to within a Frame. 
    /// </summary> 
    public sealed partial class MainPage : Page 
     { 
     private MediaCapture captureMgr { get; set; } 

     public MainPage() 
     { 
     this.InitializeComponent(); 
     this.InitCapture(); 
     } 

     private void btnTerminateApp_OnClick(object sender, RoutedEventArgs e) 
     { 
     this.ReleaseCapture(); 
     Application.Current.Exit(); 
     } 

     private async void btnCapture_OnClick(object sender, RoutedEventArgs e) 
     // Capture the barcode photo and translate it into a barcode number. And then 
     // use the barcode number to mark the piece as checked out. 
     { 
     // Capture the barcode and translate it into a barcode number. 

     //....Capture the barcode photo from the camera to a storage-file. 
     ImageEncodingProperties fmtImage = ImageEncodingProperties.CreateJpeg(); 
     StorageFile storefile = await ApplicationData.Current.LocalFolder.CreateFileAsync 
      (
      "BarcodePhoto.jpg", 
      CreationCollisionOption.GenerateUniqueName 
      ); 
     await this.captureMgr.CapturePhotoToStorageFileAsync(fmtImage, storefile); 

     //....Convert the barcode photo in the storage file into a writeable-bitmap. 
     IRandomAccessStream stream = await storefile.OpenAsync(FileAccessMode.Read); 
     BitmapDecoder decoderBmp = await BitmapDecoder.CreateAsync(stream); 
     WriteableBitmap bmp = new WriteableBitmap((int)decoderBmp.PixelWidth, 
                (int)decoderBmp.PixelHeight); 
     bmp.SetSource(stream); 

     //....We are done with the temporary barcode image file. Delete it. 
     await storefile.DeleteAsync(); 

     ////....Translate the barcode photo from the writeable-bitmap into a barcode number. 
     // 
     //ZXing.BarcodeReader bcodeReader = new ZXing.BarcodeReader(); 
     // 
     //BarcodeFormat[] aAllowedFormat = new BarcodeFormat[] { BarcodeFormat.CODE_39 }; 
     //bcodeReader.Options.PossibleFormats = aAllowedFormat; 
     // // We only want it to deal with one barcode format. Hopefully this will reduce the 
     // // chance of reading the barcode number wrong, or speed up the decoding process. 
     // // Note that this option only works if we includes "Microphone" as a required 
     // // DeviceCapability of this app in Package.appmanifest. If we don't include 
     // // "Microphone", we will get an unhandled exception here. 
     // 
     //bcodeReader.Options.TryHarder = true; // Try this option to see if we can reduce the 
     //          // chance of failing to translate the 
     //          // barcode into a number. So far no problem 
     //          // as of 11/21/2016. 
     // 
     //var result = bcodeReader.Decode(bmp); 
     //if (result == null) 
     // return; 
     } 

     private async void InitCapture() 
     // Initialize everything about MediaCapture. 
     { 
     this.captureMgr = new MediaCapture(); 
     await this.captureMgr.InitializeAsync(); 

     // Skip the steps to set the photo resolution to the second lowest in order 
     // not to make this test program too big. 

     // Start the camera preview. 
     captureElement.Source = this.captureMgr; 
     await this.captureMgr.StartPreviewAsync(); 

     // Set the camera to auto-focus. 
     var settings = new FocusSettings { Mode   = FocusMode.Continuous, 
              AutoFocusRange = AutoFocusRange.FullRange }; 
     await this.captureMgr.VideoDeviceController.FocusControl.UnlockAsync(); 
     this.captureMgr.VideoDeviceController.FocusControl.Configure(settings); 
     await this.captureMgr.VideoDeviceController.FocusControl.FocusAsync(); 

     // Turn on the flashlight in case the lighting is dim. Without enough 
     // lighting, the auto-focus feature of the camera cannot work. 
     var cameraFlashLight = this.captureMgr.VideoDeviceController.FlashControl; 
     if (cameraFlashLight.Supported) 
      { 
      if (cameraFlashLight.PowerSupported) 
       cameraFlashLight.PowerPercent = 100; 
      cameraFlashLight.Enabled = true; 
      } 
     // ////////////////////////// 
     // Tried replacing flashlight with torch. But get the same problem. 
     // ////////////////////////// 
     //var cameraTorch = this.captureMgr.VideoDeviceController.TorchControl; 
     //if (cameraTorch.Supported) 
     // { 
     // if (cameraTorch.PowerSupported) 
     //  cameraTorch.PowerPercent = 100; 
     // cameraTorch.Enabled = true; 
     // } 
     // ////////////////////////// 
     } 

     private async void ReleaseCapture() 
     { 
     captureElement.Source = null; 
     await this.captureMgr.StopPreviewAsync(); 
     this.captureMgr.Dispose(); 
     } 
     } 
    } 

하지하기 위해 :

<Page 
    x:Class="TestApp.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:TestApp" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <CaptureElement Name="captureElement" 
         Stretch="UniformToFill" 
         Margin="32,-93,34.5,181.5" 
         d:LayoutOverrides="LeftPosition, RightPosition, TopPosition, BottomPosition" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" > 
     <CaptureElement.RenderTransform> 
      <CompositeTransform Rotation="90"/> 
     </CaptureElement.RenderTransform> 
     </CaptureElement> 
     <Button x:Name="btnCapture" Content="Capture Barcode" HorizontalAlignment="Left" Margin="10,0,0,203" VerticalAlignment="Bottom" Height="64" BorderThickness="2,2,4,4" Background="#33FFFFFF" BorderBrush="Black" FontSize="20" FontWeight="Bold" Click="btnCapture_OnClick" Width="340"/> 
     <Button x:Name="btnTerminateApp" Content="Terminate This App" HorizontalAlignment="Stretch" Height="66" Margin="10,0,10,42" VerticalAlignment="Bottom" Background="#33FFFFFF" BorderBrush="Black" BorderThickness="2,2,4,4" FontWeight="Bold" d:LayoutOverrides="LeftPosition, RightPosition" Click="btnTerminateApp_OnClick" FontSize="20"/> 

    </Grid> 
</Page> 

그것은 테스트 응용 프로그램에서 MainPage.xaml.cs를 프로그램 파일이 위의 테스트 앱을 사용하기 위해 사람들에게 ZXing 라이브러리를 설치하도록 강요하십시오. 테스트 앱에서 ZXing 라이브러리와 관련된 모든 것을 주석 처리했습니다.

사용자는 해당 페이지를 떠날 때 (그리고 기본 메뉴로 돌아 가기) 문제를 해결하고 바로 같은 페이지로 돌아갈 수 있습니다. 이렇게하면 프로그램에서 무언가가 재설정되고 자동 플래시 기능이 다시 작동합니다. 분명히 이것은 사용자가 모든 단일 바코드 복용에 대해 이것을 수행해야하기 때문에 좋은 해결책이 아닙니다. 위에 표시된 테스트 응용 프로그램에는 페이지가 하나만 있고 기본 메뉴가 없습니다. 따라서 위의 테스트 응용 프로그램을 사용하여이 해결 방법을 볼 수 없습니다.

모든 사진을 찍은 후 MediaCapture를 재설정하여이 문제를 해결하려고했습니다. 이것은 위에 나와있는 테스트 응용 프로그램에서 ReleaseCapture() 및 InitCapture()를 호출하여 수행됩니다. 불행히도 이것은 각각의 바코드 캡쳐 속도를 늦출뿐만 아니라 객체가 초기화되지 않았거나 그와 유사한 것이므로 System.ObjectDisposedException을 발생시킵니다. 어쨌든, 나는 대안을 사용하는 대신 원래의 문제를 해결하는 것을 선호한다.

그건 그렇고, 제 개발 PC에는 Windows 10 Professional과 Visual Studio 2015 Professional이 있습니다. 내가 사용중인 Windows 전화는 Windows 10 Moblile 버전 1511 OS 내장 10.0.10586.107이있는 Microsoft Lumia 640 LTE입니다.

이 문제를 해결하는 데 도움을주십시오. 또한 제안을 환영합니다.

미리 감사드립니다.

제이 찬

+0

의견이 있으십니까? 저에게 알려주세요. 감사. –

+0

나는 손전등이나 토치 대신 "램프"를 사용하려고했습니다. 불행하게도 Windows Phone은 Lamp API를 지원하지 않습니다. 누군가가 가지고있는 것과 같은 문제가있는 경우,이 기사를 읽고 램프가 작동하는지 확인하고 싶을 수 있습니다. [link] https://msdn.microsoft.com/en-us/windows/uwp/audio -video-camera/camera-independent-flashlight –

+0

Lumia 640 빌드 1607에서 코드를 테스트 했으므로 플래시 라이트가 항상 잘 작동 할 수 있습니다. OS 버전을 업데이트하여 1607을 빌드하십시오. –

답변

0

아주 간단합니다.

this.ReleaseCapture(); 
this.InitCapture(); 

ReleaseCapture의 까다로운 부분은() 나는 MediaCapture을 폐기 할 수 없다는 것입니다 : 내가해야 할 일은 다음과 같이를 다시 초기화 한 후 먼저 출시하여 CaptureElement를 재설정하는 것입니다.그렇지 않으면 CaptureElement를 다시 초기화하려고하면 프로그램이 중단됩니다. 따라서 ReleaseCapture()는 지금과 같다 :

private async void ReleaseCapture() 
    // Release the resources used for capturing photo. 
    { 
    try 
     { 
     captureElement.Source = null; 
     await this.captureMgr.StopPreviewAsync(); 

     ////////////// 
     // Don't dispose it. Otherwise, when we re-initialize it right after we have released it, the program will 
     // crash. We are better off don't do this here. When we are leaving the page, the page will release it 
     // anyway. 
     ////////////// 
     //this.captureMgr.Dispose(); 
     ///////////////////////////// 
     } 
    catch(Exception ex) 
     { 
     String sErrMsg = String.Concat("Fail to release resources related to the ", 
             "use of the camera. The error message is: ", 
             ex.Message); 
     await new MessageDialog(sErrMsg, "Error").ShowAsync(); 
     } 
    } 

다른 일들이 내가이 CaptureElement을 초기화 할 때 토치와 플래시의 사용을 교체해야한다는 것입니다. 그 이유는 토치를 사용하여 연속 조명을 선호하기 때문입니다. 틀림없이 이것은이 문제와 관련이 없습니다. 하지만 InitCapture()이 버전은 내 원래 하나에서 다른 보이는 이유는 단지 설명하기 위해 언급 : 나는 세 가지 윈도우 모바일 (10) 폰이를 시도

private async void InitCapture() 
    // Initialize everything about MediaCapture. 
    { 
    this.captureMgr = new MediaCapture(); 
    await this.captureMgr.InitializeAsync(); 

    // Skip the steps to set the photo resolution to simplify 
    // the sample program. 

    // Start the camera preview. 
    captureElement.Source = this.captureMgr; 
    await this.captureMgr.StartPreviewAsync(); 

    // Ask the camera to auto-focus now. 
    var focusControl = this.captureMgr.VideoDeviceController.FocusControl; 
    var settings = new FocusSettings { Mode   = FocusMode.Continuous, 
             AutoFocusRange = AutoFocusRange.FullRange }; 
    focusControl.Configure(settings); 
    await focusControl.FocusAsync();  // Wait for the camera to focus 

    // Turn on the torch in case the lighting is dim. Without enough 
    // lighting, the auto-focus feature of the camera cannot work. 
    var cameraTorch = this.captureMgr.VideoDeviceController.TorchControl; 
    if (cameraTorch.Supported) 
     { 
     if (cameraTorch.PowerSupported) 
     cameraTorch.PowerPercent = 100; 
     cameraTorch.Enabled = true; 
     } 

    #region Error handling 
    MediaCaptureFailedEventHandler handler = (sender, e) => 
     { 
     System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Run(async() => 
     { 
     await new MessageDialog("There was an error capturing the video from camera.", "Error").ShowAsync(); 
     }); 
     }; 

    this.captureMgr.Failed += handler; 
    #endregion 
    } 

. 그들은 모두 작동합니다.

희망이 있으면 도움이됩니다.

제이 찬

+0

어떤 식 으로든이 방법 (캡처 미디어 재설정)은 전화에 손전등이나 토치 (예 : Lumia 635)가없는 경우 프로그램 충돌이 자주 발생합니다. 따라서 누군가이 방법을 사용하려면 캡처 미디어를 재설정하기 전에 장치에 손전등이나 토치가 있는지 확인해야합니다. 물론, 장치에 손전등이나 토치가 없으면이 방법을 사용할 필요가 없습니다. –