我正在使用Windows 10平臺的通用Windows應用程序。應用程序應該使用相機捕獲條形碼,並對條形碼執行一些有用的操作。到目前爲止,捕捉和翻譯條形碼工作正常(使用ZXing Library)。我可以通過單擊每個條形碼一次的按鈕來一次接一個地捕獲條形碼。我的通用Windows應用程序中的相機手電筒僅適用於一次
但我需要它在光線不足的情況下工作。我想讓攝像頭在光線不足的情況下自動打開手電筒(或手電筒)。我發現相機可以在弱光情況下自動打開手電筒(或手電筒)之前我拍了第一張照片。不知何故,第一張照片後手電筒會自動關閉。只要用戶仍然留在我的應用程序的同一頁面(只要環境很暗),我就希望它保持開啓狀態。請幫我解決這個問題。
到目前爲止,我可以確定MediaCapture.CapturePhotoToStorageFileAsync()是關閉手電筒的命令。
下面是一個工作測試程序,以解決這個問題。
它是在測試程序MainPage.xaml中的程序文件:
<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中的程序文件:
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();
}
}
}
爲了不強迫人們安裝ZXing Library只是爲了試用上面的測試應用程序,我已經在測試應用程序中評論了與ZXing Library相關的所有內容。
用戶可以通過離開該頁面(回到主菜單)然後返回到同一頁面來解決該問題。這會重置程序中的某些內容,並使自動手電筒功能再次運行。顯然,這不是一個很好的解決方法,因爲用戶需要爲每一個條碼採取這樣的操作。請注意,上面顯示的測試應用程序只有一個頁面,並沒有主菜單。因此,您將無法使用上述測試應用程序查看此解決方法。
我試圖通過在拍攝每張照片後重置MediaCapture來解決此問題。這是通過在我上面顯示的測試應用程序中調用ReleaseCapture()和InitCapture()來完成的。不幸的是,這不僅會減慢條碼的每次捕獲速度,而且還會觸發System.ObjectDisposedException關於對象未初始化或類似的事情。無論如何,我更喜歡修復原來的問題,而不是使用解決方法。
順便說一下,在我的開發PC中,我有Windows 10 Professional和Visual Studio 2015 Professional。我使用的Windows手機是帶有Windows 10 Moblile 1511操作系統 - 內置10.0.10586.107的Microsoft Lumia 640 LTE。
請幫我解決這個問題。也歡迎任何建議。
在此先感謝。
Jay Chan
有什麼建議嗎?請告訴我。謝謝。 –
我曾嘗試使用「燈」代替手電筒或手電筒。不幸的是,我正在測試的Windows Phone不支持Lamp API。以防萬一有人遇到同樣的問題,他可能想閱讀本文,以查看Lamp是否適合您:[link] https://msdn.microsoft.com/en-us/windows/uwp/audio -video-camera/camera-independent-flashlight –
我已經在Lumia 640 build 1607上測試過你的代碼,閃光燈總是可以正常工作。請嘗試更新您的操作系統版本以建立1607. –