Я работаю над универсальным приложением Windows в платформе Windows 10. Предполагается, что приложение использует камеру для захвата штрих-кода и делает что-то полезное со штрих-кодом. Пока что он отлично работает с захватом и переводом штрих-кода (с использованием библиотеки ZXing). Я могу использовать его для захвата штрих-кода один за другим, нажав кнопку один раз для каждого штрих-кода.Фонарик камеры в моем универсальном приложении для 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, чтобы попробовать тестовое приложение выше, я прокомментировал все, что связано с библиотекой ZXing в тестовом приложении.
Пользователь может решить проблему, оставив эту страницу (и обратно в главное меню), а затем перейдя вправо на ту же страницу. Это сбрасывает что-то в программе и снова активирует функцию автофокуса. Очевидно, что это нехорошее обходное решение, потому что пользователю нужно делать это для каждого отдельного штрих-кода. Обратите внимание, что тестовое приложение, показанное выше, имеет только одну страницу и не имеет главного меню. Таким образом, вы не сможете увидеть это обходное решение, используя тестовое приложение выше.
Я попытался обход этого путем сброса MediaCapture после того, как вы сделали каждую фотографию. Это делается путем вызова ReleaseCapture() и InitCapture() в моем тестовом приложении, показанном выше. К сожалению, это не только замедляет каждый захват штрих-кода, но также вызывает срабатывание System.ObjectDisposedException об объекте не инициализируется или что-то в этом роде. Во всяком случае, я предпочитаю исправить исходную проблему вместо использования обходного пути.
Кстати, на моем ПК разработки у меня есть Windows 10 Professional и Visual Studio 2015 Professional. Телефон Windows, который я использую, - это Microsoft Lumia 640 LTE с Windows 10 Moblile версии 1511 OS-Built 10.0.10586.107.
Пожалуйста, помогите мне решить эту проблему. Также приветствуем любое предложение.
Заранее спасибо.
Джей Чан
Любое предложение? Пожалуйста, дайте мне знать. Благодарю. –
Я попытался использовать «Лампу» вместо фонарика или фонарика. К сожалению, 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. –