0

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?

hotkey
  • 140,743
  • 39
  • 371
  • 326
AviGe
  • 13
  • 3

2 Answers2

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.

Community
  • 1
  • 1
Abhishek
  • 1,349
  • 8
  • 17
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