我正在用C#编写一个UWP应用程序(通用Windows应用程序),用于运行O / S周年纪念版的Windows 10手机。我正在尝试使用该应用拍摄照片,然后处理照片。问题是应用程序需要很长时间才能拍照。第一张照片需要5到6秒,后续照片每张需要3秒。另一方面,同一手机中的内置相机应用程序只需1/2秒或更短时间拍照。显然我的应用程序有问题。我将其缩小为一个需要很长时间才能完成的命令 - 即CapturePhotoToStorageFileAsync()。
请注意,我的应用程序和内置的相机应用程序都将照片保存在图片库中(Windows Phone - >手机 - >图片)。唯一的区别是我的照片可以直接保存在"图片"夹。另一方面,内置的相机应用程序将照片保存在"图片\相机胶卷"夹。我怀疑这有什么不同。
我认为我的应用可能会将照片保存在云端存储中。但是当我从手机上拔下USB线时,我仍然遇到同样的问题,我已经关闭了手机上的WiFi(手机没有数据计划)。我已经验证了设置 - >系统 - >存储照片应保存在"本设备"。
手机的速度无关紧要,因为如上所述,内置的相机应用可以在同一部手机中快速拍摄照片。这意味着手机的硬件能够非常快速地拍摄照片。因此,这不是硬件问题。
该应用程序在调试器下或调试器外运行时遇到同样的问题。
当我在" Debug"中构建它时,应用程序会遇到同样的问题。模式或在"发布"模式。
我准备了一个简化版的应用程序供您审核。希望你能发现我没有注意到的错误。
MainPage.xaml中
<Page
x:Class="Checkout.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Checkout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Loaded="OnLoaded">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="4*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<CaptureElement x:Name="captureElement" Grid.Row="0" Stretch="Uniform" />
<Button x:Name="btnCapture" Grid.Row="1" Content="Capture Photo" Click="btnCapture_OnClick" />
<TextBlock x:Name="lblMsg" Grid.Row="2" Text="Show message here" />
<Button x:Name="btnTerminateApp" Grid.Row="3" Content="Terminate App" Click="btnTerminateApp_OnClick" />
</Grid>
</Page>
MainPage.xaml.cs中
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Devices.Enumeration; // For DeviceInformation, DeviceClass.
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Capture; // For MediaCapture.
using Windows.Media.Devices; // For FocusSettings, FocusMode, AutoFocusRange.
using Windows.Media.MediaProperties; // For ImageEncodingProperties.
using Windows.Storage; // For StorageFile.
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.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace Checkout
{
/// <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();
}
private void OnLoaded( object sender, RoutedEventArgs e )
{
this.lblMsg.Text = "";
// Create a new instance of MediaCapture and start the camera in preview mode.
this.InitCapture();
}
private async void btnCapture_OnClick( object sender, RoutedEventArgs e )
{
// Acknowledge that the user has triggered a button to capture a barcode.
this.lblMsg.Text = "-------";
// Capture the photo from the camera to a storage-file.
ImageEncodingProperties fmtImage = ImageEncodingProperties.CreateJpeg();
StorageLibrary libPhoto = await StorageLibrary.GetLibraryAsync( KnownLibraryId.Pictures );
StorageFile storefile =
await libPhoto.SaveFolder.CreateFileAsync( "BarcodePhoto.jpg",
CreationCollisionOption.ReplaceExisting );
await this.captureMgr.CapturePhotoToStorageFileAsync( fmtImage, storefile );
// Tell the user that we have taken a picture.
this.lblMsg.Text = "Picture taken";
}
private void btnTerminateApp_OnClick( object sender, RoutedEventArgs e )
{
this.ReleaseCapture();
Application.Current.Exit();
}
private async void InitCapture()
// Initialize everything about MediaCapture.
{
this.captureMgr = new MediaCapture();
await this.captureMgr.InitializeAsync();
// Use the lowest resolution in order to speed up the process.
this.SetCaptureElementToMinResolution();
// 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();
#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
}
private async void SetCaptureElementToMinResolution()
// Set the CaptureElement to the minimum resolution that the device
// can handle. We need to set it to lowest resolution in other to
// speed up the process.
{
VideoEncodingProperties resolutionMin = null;
int nMinResolutionSoFar = -1;
var lisResolution = this.captureMgr.VideoDeviceController.GetAvailableMediaStreamProperties( MediaStreamType.Photo );
for( var i = 0; i< lisResolution.Count; i++ )
{
VideoEncodingProperties resCur = (VideoEncodingProperties)lisResolution[ i ];
int nCurResolution = (int)( resCur.Width * resCur.Height );
if (nMinResolutionSoFar == -1)
{
nMinResolutionSoFar = nCurResolution;
resolutionMin = resCur;
}
else if ( nMinResolutionSoFar > nCurResolution )
{
nMinResolutionSoFar = nCurResolution;
resolutionMin = resCur;
}
}
await this.captureMgr.VideoDeviceController.SetMediaStreamPropertiesAsync( MediaStreamType.Photo, resolutionMin );
}
private async void ReleaseCapture()
// Release the resources used for capturing photo.
{
try
{
captureElement.Source = null;
await this.captureMgr.StopPreviewAsync();
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();
}
}
}
}
如果您想在计算机中试用此应用程序,请创建一个新项目,并在项目中启用以下功能:Internet(默认),麦克风和网络摄像头。然后从上面显示的那两个文件中复制代码。
请尝试一下,让我知道你的电脑/手机是怎么回事。
我的手机是Microsoft Lumia 550,Windows 10 Mobile,1GB RAM,版本1607,操作系统版本:10.0.14393.693。
提前感谢您的帮助。
杰伊陈