I need to launch the universal camera app to take a picture and to return the pic to my app. I can't use the Photo Chooser Tasks because it's unsupported on WinRT and i don't want the Media Capture. Any idea?
Asked
Active
Viewed 566 times
2 Answers
0
In Windows 8 apps, the equivalent to CameraCaptureTask is CameraCaptureUI. Unfortunately it is not available for Windows Phone 8.1. So your only option is to use MediaCapture. Check this post for details: Photo capture on Windows Store App for Windows Phone
There is also a helper class that you can use as an alternative: CameraCaptureUI for Windows Phone. However it's very elementary and lacks customization.
0
ok, let me explain how it should be implemented:
1) Create class named: CameraCapture:
public class CameraCapture : IDisposable
{
MediaCapture mediaCapture;
ImageEncodingProperties imgEncodingProperties;
MediaEncodingProfile videoEncodingProperties;
public VideoDeviceController VideoDeviceController
{
get { return mediaCapture.VideoDeviceController; }
}
public async Task<MediaCapture> Initialize(CaptureUse primaryUse = CaptureUse.Photo)
{
// Create MediaCapture and init
mediaCapture = new MediaCapture();
var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
PhotoCaptureSource = PhotoCaptureSource.Photo,
AudioDeviceId = string.Empty,
VideoDeviceId = devices[1].Id
});
mediaCapture.VideoDeviceController.PrimaryUse = primaryUse;
// Create photo encoding properties as JPEG and set the size that should be used for photo capturing
imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
imgEncodingProperties.Width = 640;
imgEncodingProperties.Height = 480;
// Create video encoding profile as MP4
videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga);
// Lots of properties for audio and video could be set here...
return mediaCapture;
}
public async Task<StorageFile> CapturePhoto(string desiredName = "warranty.jpg")
{
// Create new unique file in the pictures library and capture photo into it
var photoStorageFile = await KnownFolders.PicturesLibrary.CreateFileAsync(desiredName, CreationCollisionOption.GenerateUniqueName);
await mediaCapture.CapturePhotoToStorageFileAsync(imgEncodingProperties, photoStorageFile);
return photoStorageFile;
}
public async Task<StorageFile> StartVideoRecording(string desiredName = "video.mp4")
{
// Create new unique file in the videos library and record video!
var videoStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(desiredName, CreationCollisionOption.GenerateUniqueName);
await mediaCapture.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
return videoStorageFile;
}
public async Task StopVideoRecording()
{
// Stop video recording
await mediaCapture.StopRecordAsync();
}
public async Task StartPreview()
{
// Start Preview stream
await mediaCapture.StartPreviewAsync();
}
public async Task StartPreview(IMediaExtension previewSink, double desiredPreviewArea)
{
// List of supported video preview formats to be used by the default preview format selector.
var supportedVideoFormats = new List<string> { "nv12", "rgb32" };
// Find the supported preview size that's closest to the desired size
var availableMediaStreamProperties =
mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoPreview)
.OfType<VideoEncodingProperties>()
.Where(p => p != null && !String.IsNullOrEmpty(p.Subtype) && supportedVideoFormats.Contains(p.Subtype.ToLower()))
.OrderBy(p => Math.Abs(p.Height * p.Width - desiredPreviewArea))
.ToList();
var previewFormat = availableMediaStreamProperties.FirstOrDefault();
// Start Preview stream
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, previewFormat);
await mediaCapture.StartPreviewToCustomSinkAsync(new MediaEncodingProfile { Video = previewFormat }, previewSink);
}
public async Task StopPreview()
{
// Stop Preview stream
await mediaCapture.StopPreviewAsync();
}
public void Dispose()
{
if (mediaCapture != null)
{
mediaCapture.Dispose();
mediaCapture = null;
}
}
}
2) Add MediaElement to you xaml Page code:
<Grid Background="#FF40B9F5">
<Grid.RowDefinitions>
<RowDefinition Height="543*"/>
<RowDefinition Height="97*"/>
</Grid.RowDefinitions>
<CaptureElement x:Name="CapturePreview" Grid.Row="0"/>
<Button x:Name="TakeWarrantyPhoto_Button" Content="TAKE PHOTO" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Center" Click="TakeWarrantyPhoto_Button_Click" BorderBrush="Black" Foreground="Black" FontFamily="Book Antiqua" FontWeight="Bold"/>
</Grid>
3) Page C# code:
public sealed partial class AddNewWarrantyPhotoPage : Page
{
private CameraCapture cameraCapture;
public AddNewWarrantyPhotoPage()
{
this.InitializeComponent();
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
cameraCapture = new CameraCapture();
CapturePreview.Source = await cameraCapture.Initialize();
await cameraCapture.StartPreview();
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
// Release resources
if (cameraCapture != null)
{
await cameraCapture.StopPreview();
CapturePreview.Source = null;
cameraCapture.Dispose();
cameraCapture = null;
}
}
private async void TakeWarrantyPhoto_Button_Click(object sender, RoutedEventArgs e)
{
var photoStorageFile = await cameraCapture.CapturePhoto();
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(await photoStorageFile.OpenReadAsync());
//you can show it in your picture if you declare it in xaml:
// WarrantyPhotoDisplay_Image.Source = bitmap;
}
}
Hope it will help.

Daniel Krzyczkowski
- 2,732
- 2
- 20
- 30