问题
I am attempting to use the MediaCapture API within a Windows 8 Desktop Application (WinForms .NET 4.5). I am able to take the photo using the API, but the photo comes out very dark. Also, it does not appear that the MediaCapture API is triggering the camera flash automatically as it should.
I have tried to set the Brightness, Contracts, WhiteBalance and exposure to automatic per MSDN documentation. Here is the relevant code.
_mediaCapture = new MediaCapture();
// init the settings of the capture
var settings = new MediaCaptureInitializationSettings();
settings.AudioDeviceId = "";
settings.VideoDeviceId = _currentDeviceId;
settings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.Photo;
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
await _mediaCapture.InitializeAsync(settings);
// Find the highest resolution available
ImageEncodingProperties resolutionMax = null;
int max = 0;
var resolutions = _mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);
foreach (IMediaEncodingProperties t in resolutions)
{
var properties = t as ImageEncodingProperties;
if (properties != null)
{
var res = properties;
if (res.Width * res.Height > max)
{
max = (int)(res.Width * res.Height);
resolutionMax = res;
}
}
}
await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, resolutionMax);
_mediaCapture.VideoDeviceController.Focus.TrySetAuto(true);
_mediaCapture.VideoDeviceController.Brightness.TrySetAuto(true);
_mediaCapture.VideoDeviceController.Contrast.TrySetAuto(true);
_mediaCapture.VideoDeviceController.Exposure.TrySetAuto(true);
_mediaCapture.VideoDeviceController.WhiteBalance.TrySetAuto(true);
var imageProperties = ImageEncodingProperties.CreateJpeg();
using (var fPhotoStream = new InMemoryRandomAccessStream())
{
// Take the photo and show it on the screen
await _mediaCapture.CapturePhotoToStreamAsync(imageProperties, fPhotoStream);
await fPhotoStream.FlushAsync();
fPhotoStream.Seek(0);
var bytes = new byte[fPhotoStream.Size];
await fPhotoStream.ReadAsync(bytes.AsBuffer(), (uint)fPhotoStream.Size, InputStreamOptions.None);
using (var byteStream = new MemoryStream(bytes))
{
return new Bitmap(byteStream);
}
}
Any guidance would be much appreciated.
EDIT: I ported this code to a Metro app and the camera works beautifully. I am beginning to think that the underlying framework (Metro vs. Desktop) is to blame.
回答1:
Late reply, but in case that helps folks in the future: dark pictures are often due to the lack of video preview. Camera drivers use the preview stream to run their 3A algorithms (auto-whitebalance/focus/exposure). At the moment getting MediaCapture to preview in Desktop apps is a bit challenging. One way to do it is to create a D3DImage and rely on some native interop to call Media Foundation and DirectX. It is not trivial but can be encapsulated so the C# API surface remains simple. Here is some code sample: https://github.com/mmaitre314/MediaCaptureWPF
回答2:
You can try to change your media settings as following, it should be better:
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.AudioAndVideo;
settings.PhotoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.VideoPreview;
回答3:
await mc.InitializeAsync(new MediaCaptureInitializationSettings {
PhotoCaptureSource = PhotoCaptureSource.VideoPreview }
);
is the solution.
来源:https://stackoverflow.com/questions/15390861/mediacapture-windows-8-desktop-photo-is-dark