简体   繁体   English

拍摄照片

[英]Capture a photo

I have problem with capturing a photo. 拍摄照片时出现问题。 I have tried to solve this for 3 days, I hope that you will help me with this. 我已经尝试解决了3天,希望您对此有所帮助。

My xaml : 我的xaml:

<CaptureElement x:Name="capturePreview" Stretch="Uniform" Grid.Column="0" Height="200" Width="300"
                                VerticalAlignment="Center" HorizontalAlignment="Center"/>

            <Image x:Name="imagePreivew" Stretch="Uniform" Grid.Column="1"
                       VerticalAlignment="Center" HorizontalAlignment="Stretch"/>

            <StackPanel Orientation="Horizontal">
                <Button Click="InitCameraBtn_Click" Content="Initialize Camera" />
                <Button Click="StartPreviewBtn_Click" Content="Start Capture Preview" />
                <Button Click="TakePhotoBtn_Click" Content="Capture Photo"/>
            </StackPanel>

and my cs 和我的CS

private Windows.Media.Capture.MediaCapture captureManager;
    public MainPage()
    {
        this.InitializeComponent(); 
    }

    private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desiredCamera)
    {
        // get available devices for capturing pictures
        DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
            .FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredCamera);

        if (deviceID != null) return deviceID;
        else throw new Exception(string.Format("Camera of type {0} doesn't exist.", desiredCamera));
    }

    async private void InitCameraBtn_Click(object sender, RoutedEventArgs e)
    {
        var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
        captureManager = new MediaCapture();

        await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
        {
            StreamingCaptureMode = StreamingCaptureMode.Video,
            PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
            AudioDeviceId = string.Empty,
            VideoDeviceId = cameraID.Id
        });

        var maxResolution = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo).Aggregate((i1, i2) => (i1 as VideoEncodingProperties).Width > (i2 as VideoEncodingProperties).Width ? i1 : i2);
        await captureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, maxResolution);
    }

    async private void StartPreviewBtn_Click(object sender, RoutedEventArgs e)
    {
        // rotate to see preview vertically
        captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
        capturePreview.Source = captureManager;
        await captureManager.StartPreviewAsync();
    }

    async private void TakePhotoBtn_Click(object sender, RoutedEventArgs e)
    {
        // create a file
        StorageFile photoFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("myFirstPhoto.jpg", CreationCollisionOption.ReplaceExisting);

        // take a photo with choosen Encoding
        await captureManager.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), photoFile);

        // we can also take a photo to memory stream
        // InMemoryRandomAccessStream memStream = new InMemoryRandomAccessStream();
        // await captureManager.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpegXR(), memStream);

        // show a photo on screen
        BitmapImage bitmapToShow = new BitmapImage(new Uri(photoFile.Path));
        imagePreivew.Source = bitmapToShow;  // show image on screen inside Image control defined in XAML
    } 
public void Dispose()
{
    if (mediaCapture != null)
    {
        mediaCapture.Dispose();
        mediaCapture = null;
    }
}

What am I doing wrong? 我究竟做错了什么? If I click initliaze nothing is going to do I cant even see camera when I click other buttons I get an exception like this: + 如果单击“初始化”,则什么也没做,即使单击其他按钮,我也看不到相机,但出现如下异常:+

$exception  {System.Exception: The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action. (Exception from HRESULT: 0x887A0005)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Save_bills.MainPage.<TakePhotoBtn_Click>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)
   at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()}    System.Exception

and

 +      $exception  {System.Exception: The text associated with this error code could not be found.

The text associated with this error code could not be found.

   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Save_bills.MainPage.<InitCameraBtn_Click>d__a.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)
   at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()}    System.Exception

You are facing this issue beacause you are not Disposing your MediaCapture object, what is very important when dealing with camera. 因为您没有处理 MediaCapture对象,所以面对此问题是非常重要的。 I suspect that after you debug your app and exit it without disposing, you will have problem to run the normal camera app on the phone. 我怀疑在调试应用程序并退出而不进行处置后,您将无法在手机上运行普通相机应用程序。

What you should do is to stop camera preview when it's not needed and dispose the capture element. 您应该做的是在不需要时停止相机预览,并放置捕获元素。 When to do it? 什么时候做? It depends on few things: 这取决于几件事:

  • think of Suspending event of your app , remember only that this event is not called when you are debugging, 考虑到应用程序Suspending事件,请记住,调试时不会调用此事件,
  • you may also use Window's events like WindowActivated / VisibilityChanged 您还可以使用Window的事件,例如WindowActivated / VisibilityChanged

For the purpose of a test, do such a thing - in the method taking photo, at the end, call method stopping preview and call MediaCapture.Dispose . 为了进行测试,请执行以下操作-在拍照方法中,最后,调用停止预览的方法并调用MediaCapture.Dispose When you do this, debug the app, take a photo, stop debugging. 执行此操作时,调试应用程序,拍照,然后停止调试。 If you do this, you should be able to initialize the camera without problems next time you start the app. 如果执行此操作,则下次启动该应用程序时,应该能够毫无问题地初始化相机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM