Use MediaCapture on a Windows 8 desktop app

17,678

Late reply, but in case that helps folks in the future: previewing MediaCapture in WPF can be done via D3DImage and some native interop (create a custom Media Foundation Sink, grab DirectX 11 textures, convert them to DirectX 9). It is a bit of code but can be encapsulated so it is still simple to call from C#. Here is some code sample: https://github.com/mmaitre314/MediaCaptureWPF

Share:
17,678
Admin
Author by

Admin

Updated on June 06, 2022

Comments

  • Admin
    Admin almost 2 years

    On a Windows 8 desktop app, I need to take a photo using the camera in C# 4.5.

    I've tried to use the CameraCaptureUI class, but it is not available on a desktop app.

    So I try to use the MediaCapture class, which is available for Metro app or desktop app. It works great, based on the example found here : http://code.msdn.microsoft.com/windowsapps/media-capture-sample-adf87622/

    var capture = new MediaCapture();
    // Find the camera device id to use
    string deviceId = "";
    var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(Windows.Devices.Enumeration.DeviceClass.VideoCapture);
    for (var i = 0; i < devices.Count; i++) {
         Console.WriteLine(devices[i]);
         deviceId = devices[i].Id;
    }
    
    // init the settings of the capture
    var settings = new MediaCaptureInitializationSettings();
    settings.AudioDeviceId = "";
    settings.VideoDeviceId = deviceId;
    settings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.Photo;
    settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
    await capture.InitializeAsync(settings);
    
    // Find the highest resolution available
    VideoEncodingProperties resolutionMax = null;
    int max = 0;
    var resolutions = capture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);
    for (var i = 0; i < resolutions.Count; i++) {
         VideoEncodingProperties res = (VideoEncodingProperties)resolutions[i];
         Console.WriteLine("resolution : " + res.Width + "x" + res.Height);
         if (res.Width * res.Height > max) {
              max = (int)(res.Width * res.Height);
              resolutionMax = res;
         }
    }
    await capture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, resolutionMax);
    
    ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
    var fPhotoStream = new InMemoryRandomAccessStream();
    
    // THE 2 LINES I NEED TO ADD
    // captureElement.Source = capture;
    // await capture.StartPreviewAsync();
    
    // Take the photo and show it on the screen
    await capture.CapturePhotoToStreamAsync(imageProperties, fPhotoStream);
    await fPhotoStream.FlushAsync();
    fPhotoStream.Seek(0);
    
    byte[] bytes = new byte[fPhotoStream.Size];
    await fPhotoStream.ReadAsync(bytes.AsBuffer(), (uint)fPhotoStream.Size, InputStreamOptions.None);
    
    BitmapImage bitmapImage = new BitmapImage();
    MemoryStream byteStream = new MemoryStream(bytes);
    bitmapImage.BeginInit();
    bitmapImage.StreamSource = byteStream;
    bitmapImage.EndInit();
    image.Source = bitmapImage;
    

    I can take a photo using the camera, but I'm unable to show a preview before taking the photo. To be able to show the preview, I have to use the component CaptureElement, for example with the following code :

    captureElement.Source = mediaCapture;
    await mediaCapture.startPreviewAsync();
    

    Unfortunately, I cannot use a CaptureElement on a non store app. Is there another component that I can use in a WPF or WinForm app, to be able to show the preview of the camera ?

  • Tarec
    Tarec almost 10 years
    A link to a potential solution is always welcome, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline.