-1

I have a simple photo capture functionality made for windows phone 10 in C#.

Capture setup:

                _captureManager = new MediaCapture();

                await _captureManager.InitializeAsync(new MediaCaptureInitializationSettings
                {
                    StreamingCaptureMode = StreamingCaptureMode.Video,
                    PhotoCaptureSource = PhotoCaptureSource.Photo,
                    AudioDeviceId = string.Empty,
                    VideoDeviceId = cameraId
                });


                var resolutions = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);

                // Here I choose same resolution as native camera does
                await _captureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, resolutions[3]); 

And I capture photo:

using (var imageStream = new InMemoryRandomAccessStream())
            {
                var format = ImageEncodingProperties.CreateJpeg();
                var capturefile = await _storeFolder.CreateFileAsync(photoName, CreationCollisionOption.GenerateUniqueName);

                await _captureManager.CapturePhotoToStreamAsync(format, imageStream); 

.....
}

However on CapturePhotoToStreamAsync my picture gets cropped. This does not happen when I remove SetMediaStreamPropertiesAsync, but it selects different resolution then my native camera does.

Does anyone know what could be the cause of this problem?

user2081328
  • 159
  • 3
  • 15
  • `resolutions[3]` - what's `3`? – IInspectable Mar 02 '17 at 14:58
  • Third member of the list of media stream properties (the one that is same as my native camera). Never mind that, it is work in progress, later I will programmatically select best resolution based on aspect ration. The issue is that when I change media stram properties, my picture gets cropped. – user2081328 Mar 02 '17 at 15:10
  • 1
    It's a magic number, and whenever I see a magic number I have to ask, what it means. Your response wasn't very enlightening (and wrong, too). It is the fourth member, but we have no way of knowing, what's stored in the fourth member. It could be what you're looking for or something else altogether. If you need help, don't make the code harder to read than it needs to be. – IInspectable Mar 02 '17 at 15:20
  • "Never mind that" part of the answer was important, and enlightening enough. I have tried selecting each member including the default one, the issue is probably with MediaCapture itself. Any useful ideas? – user2081328 Mar 02 '17 at 15:49
  • Alright then, you are having problems setting properties, yet you insist that you need not share, which properties you are trying to set, nor which properties you really are setting. That type of question is off-topic, because it's not useful to anyone (nor answerable). – IInspectable Mar 02 '17 at 16:06
  • Is this [the same problem as here](http://stackoverflow.com/q/23709547/2681948)? – Romasz Mar 02 '17 at 16:09
  • There is nothing more to share. Properties are set at SetMediaStreamPropertiesAsync. There is a list of available properties from GetAvailableMediaStreamProperties, I pick any and set it using SetMediaStreamPropertiesAsync. – user2081328 Mar 02 '17 at 16:17
  • @Romasz - this might be it, I'll check it tomorrow, thanks. – user2081328 Mar 02 '17 at 16:18
  • 1
    Maybe, maybe not. I'm pretty sure it's not that simple. [Set format, resolution, and frame rate for MediaCapture](https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/set-media-encoding-properties) appears to agree with me: *"It is possible, on some devices, to set a different aspect ratio for the camera's preview stream and capture stream. Frame cropping caused by this mismatch can result in content being present in the captured media that was not visible in the preview which can result in a negative user experience."* – IInspectable Mar 02 '17 at 16:21
  • @IInspectable I agree with you, generally thinking - cameras are designed to work with specific resolutions, if user/developer want different resolution then he can probably crop the image after taking a picture. – Romasz Mar 02 '17 at 16:28

1 Answers1

0

Ok, I found the answer, so to add if someone needs it. Resolution of my camera is 1.64*. For this resolution, aspect ratio 16:9 (1.77*) does not work. So when I tried to set it, it would fail. Since this resolution works on native camera, I thought that there should be some setting to make it work.

But I made a workaround. First I save photo resolution info from:

var _photoResolution = VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo)

After this, when capturing photo, I use BitmapDecoder to change captured image to desired resolution:

 using (var imageStream = new InMemoryRandomAccessStream())
            {
                var photoName = $"myPhoto.jpg";
                var capturefile = await _storeFolder.CreateFileAsync(photoName, CreationCollisionOption.GenerateUniqueName);

                await _captureManager.CapturePhotoToStreamAsync(format, imageStream);

                var dec = await BitmapDecoder.CreateAsync(imageStream);
                var enc = await BitmapEncoder.CreateForTranscodingAsync(imageStream, dec);

                enc.BitmapTransform.ScaledHeight = _photoResolution.Height;
                enc.BitmapTransform.ScaledWidth = _photoResolution.Width;

                // bounds must be set for ScaledHeight and ScaledWidth transform would work, but I don't know why
                // based on device orientation, I am setting proper value for width and height
                var bounds = new BitmapBounds
                {
                    Height = ((deviceOrientation == Enums.DeviceOrientation.Portrait || deviceOrientation == Enums.DeviceOrientation.Flipped) ? _photoResolution.Width : _photoResolution.Height) - 1,
                    Width = ((deviceOrientation == Enums.DeviceOrientation.Portrait || deviceOrientation == Enums.DeviceOrientation.Flipped) ? _photoResolution.Height : _photoResolution.Width) - 1,
                    X = 1,
                    Y = 1
                };
                enc.BitmapTransform.Bounds = bounds;

                await enc.FlushAsync();

                using (var fileStream = await capturefile.OpenStreamForWriteAsync())
                {
                    await RandomAccessStream.CopyAsync(imageStream, fileStream.AsOutputStream());
                }                    
            }
user2081328
  • 159
  • 3
  • 15