none
Silverlight Web Camera Image Quality

    Question


  • We have a Silverlight solution that allows the user to activate and take a picture with the devices camera from within their web browser. 

    To achieve this we  are using CaptureImageAsync() and  setting the capture devices format via VideoCaptureDeivce.DesiredFormat. The device format we use is the maximum available resolution for that device.

    The issue we are encountering is that on certain devices, in this case windows tablets, the DesiredFormat we set is ignored and instead the QVGA (240x320) format is used in its stead. We have debugged the project and the resolution\device format is correct up until we attempt to access the result of the CaptureImageAsync() request. 

    Is anyone able to suggest a possible solution?

    I have feeling we need to force the device to use something other than QVGA, how would we go about doing so?

    The script is as follows:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using AgilityCIS.Orion.ScriptEngine;
    using System.Linq;
    
    namespace AgilityCIS.Orion.ScriptUI.Controls.Answers
    {
        public partial class ScriptPhotoAnswer : UserControl
        {
            CaptureSource _captureSource = new CaptureSource();
            WriteableBitmap _lastSnapshot = null;
            private int deviceIndex = 0;
    
            public ScriptPhotoAnswer()
            {
                InitializeComponent();
    
                this.Unloaded += (sender, args) => _captureSource.Stop();
    
                brushCamera.SetSource(_captureSource);
            }
    
            private void ActivateCameraOnClick(object sender, RoutedEventArgs e)
            {
                if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
                {
                    _captureSource.Stop();
    
                    var devices = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
                    imgSnapshot.Visibility = Visibility.Collapsed;
                    _captureSource.VideoCaptureDevice = devices[deviceIndex];
                    SetMaxCameraResolution();
                    _captureSource.Start();
                }
            }
    
            private void SwitchCameraOnClick(object sender, RoutedEventArgs e)
            {
                _captureSource.Stop();
    
                var devices = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
    
                deviceIndex++;
                if (deviceIndex >= devices.Count)
                    deviceIndex = 0;
                _captureSource.VideoCaptureDevice = devices[deviceIndex];
                SetMaxCameraResolution();
                _captureSource.Start();
            }
    
            public void SetMaxCameraResolution()
            {
                System.Collections.ObjectModel.ReadOnlyCollection<VideoFormat> formats = _captureSource.VideoCaptureDevice.SupportedFormats;
    
                if (formats == null)
                {
                   _captureSource.VideoCaptureDevice.DesiredFormat = new VideoFormat(PixelFormatType.Unknown, 4096, 4096, 30);
                   return;
                }
                    
                var format = (from VideoFormat f in formats
                              orderby f.PixelWidth * f.PixelHeight descending
                              select f).FirstOrDefault<VideoFormat>();
    
                if (format != null)
                    _captureSource.VideoCaptureDevice.DesiredFormat = format;           
                 
            }
    
            private void TakePhotoOnClick(object sender, RoutedEventArgs e)
            {
                if (_captureSource.State == CaptureState.Started)
                {
                    _captureSource.CaptureImageCompleted += (s, a) =>
                    {
                        // At this stage a.Result is set to a 240x320 resoultion
                        _lastSnapshot = a.Result;
    
                        imgSnapshot.Visibility = Visibility.Visible;
                        imgSnapshot.Source = _lastSnapshot;
                        _captureSource.Stop();
    
                        ((ScheduleQuestion) DataContext).AnswerBitmap = _lastSnapshot;
    
                    };
    
                    // At this stage the desired format is correctly defined and resolution is as desired in the capture source
                    _captureSource.CaptureImageAsync();
                }
                else
                {
                    MessageBox.Show("Activate Camera before taking photo.  Click Activate Camera button.");
                }
            }
        }
    }

    Any suggestions would be very much appreciated.

    Wednesday, February 15, 2017 12:07 PM

All replies

  • Hi AgilityCIS-Fabian,

    Please try debug your code on two places.

    One in SetMaxCameraResolution() function and another in TakePhotoOnClick() function.

    In SetMaxCameraResolution() function, please check format variable value, make sure it has a valid which will affect the CaptureSource.VideoCaptureDevice.DesiredFormat.

    In TakePhotoOnClick() function, please set a fixed value for CaptureSource.VideoCaptureDevice.DesiredFormat before the line of "_captureSource.CaptureImageAsync();", which could help us confirm whether there has any problem on your code executed sort or the CaptureImageAsync() function.

    Best Regards,
    Weiwei


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, February 16, 2017 3:23 AM
    Moderator
  • Hi Weiwei,

    Thank you for your reply.

    I tried to debug on the two places mentioned. In both cases a valid format is picked up and the desired format is set to 1280 * 720 .

    Also, I set a fixed value for CaptureSource.VideoCaptureDevice.DesiredFormat before the line of "_captureSource.CaptureImageAsync();",  but as soon as CaptureImageAsync() function is called, and the control moves to CaptureImageCompleted the result is of size 240 * 320.

    Any further suggestion why the image is captured of low quality despite correct desiredformat property correctly set?

    Thanks.

    Thursday, February 16, 2017 9:10 AM