Capture a photo

0

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.

My 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

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
c#
xaml
windows-phone-8.1
asked on Stack Overflow Mar 13, 2015 by Icet • edited Mar 14, 2015 by Romasz

1 Answer

3

You are facing this issue beacause you are not Disposing your MediaCapture object, what is very important when dealing with camera. 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,
  • you may also use Window's events like 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. 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.

answered on Stack Overflow Mar 14, 2015 by Romasz

User contributions licensed under CC BY-SA 3.0