Search
Duplicate

Creating a UWP desktop app in C# 3/5: Taking a picture and adding a 5-second countdown function.

Published On
2024/09/11
Lang
EN
Tags
Programming
Window Development
UWP

Series

Hello! In this article, we'll implement a feature in a UWP app that takes a photo after a 5-second countdown and displays the result on the screen. When you click on the preview screen, the countdown begins, and after the photo is taken, the preview disappears and buttons for the captured photo, retake, and print are displayed.
In the previous article, we implemented the camera preview function, so this time we'll add countdown and capture functions to develop a more interactive app.

1. App Flow Plan

The flow that users will experience when using the app is as follows:
1.
On the preview screen, when the user clicks the screen, a 5-second countdown begins.
2.
When the countdown ends, a photo is taken, and the preview screen disappears.
3.
The captured photo is displayed on the screen, and retake and print buttons are shown.
4.
When the user presses the "Retake" button, it returns to the preview screen, and when they press the "Print" button (print function to be added later), they can print the photo.

2. UI Configuration

First, we'll modify MainPage.xaml to configure the UI. We've added a preview screen, an image control to display the captured photo, and a text block to show the countdown.
<Page x:Class="PhotoBooth.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:PhotoBooth" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <!-- Camera preview --> <CaptureElement x:Name="CameraPreview" HorizontalAlignment="Center" VerticalAlignment="Center" Width="640" Height="480" Grid.Row="0" Tapped="CameraPreview_Tapped"/> <!-- Countdown text --> <TextBlock x:Name="CountdownText" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="60" Visibility="Collapsed" Grid.Row="0"/> <!-- Display captured photo --> <Image x:Name="CapturedImage" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Width="640" Height="480" Grid.Row="0"/> <!-- Retake and print buttons --> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Opacity="0" x:Name="ButtonPanel" Grid.Row="1" Margin="0,10,0,10"> <Button Content="Retake" Click="RetakeButton_Click" Margin="10"/> <Button Content="Print" Click="PrintButton_Click" Margin="10"/> </StackPanel> </Grid> </Page>
XML
복사

UI Explanation

CaptureElement: A control that displays the camera preview screen.
TextBlock (CountdownText): Displays the countdown before taking a photo.
Image (CapturedImage): A control that displays the captured photo.
StackPanel (ButtonPanel): An area that displays the "Retake" and "Print" buttons after capturing a photo.

3. Implementing Photo Capture and Countdown

We will implement the countdown and photo capture functions in MainPage.xaml.cs. This includes code to switch to full-screen mode and logic to handle camera capture.
using System; using System.IO; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using Windows.Media.Capture; using Windows.Storage.Streams; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media.Imaging; namespace PhotoBooth { public sealed partial class MainPage : Page { private MediaCapture _mediaCapture; private bool _isPreviewing = true; public MainPage() { this.InitializeComponent(); // Switch to full-screen mode EnterFullScreenMode(); InitializeCameraAsync(); } private void EnterFullScreenMode() { var view = ApplicationView.GetForCurrentView(); view.TryEnterFullScreenMode(); ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen; } private async void InitializeCameraAsync() { _mediaCapture = new MediaCapture(); await _mediaCapture.InitializeAsync(); CameraPreview.Source = _mediaCapture; await _mediaCapture.StartPreviewAsync(); } private async void CameraPreview_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) { if (_isPreviewing) { await StartCountdownAndTakePhoto(); } } private async Task StartCountdownAndTakePhoto() { try { CountdownText.Visibility = Visibility.Visible; for (int i = 5; i > 0; i--) { CountdownText.Text = i.ToString(); await Task.Delay(1000); } CountdownText.Visibility = Visibility.Collapsed; await TakePhotoAsync(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"Error in StartCountdownAndTakePhoto: {ex.Message}"); } } private async Task TakePhotoAsync() { try { var renderTargetBitmap = new RenderTargetBitmap(); await renderTargetBitmap.RenderAsync(CameraPreview); var pixelBuffer = await renderTargetBitmap.GetPixelsAsync(); var bitmap = new WriteableBitmap(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight); using (var stream = bitmap.PixelBuffer.AsStream()) { await stream.WriteAsync(pixelBuffer.ToArray(), 0, (int)pixelBuffer.Length); } CapturedImage.Source = bitmap; CameraPreview.Visibility = Visibility.Collapsed; CapturedImage.Visibility = Visibility.Visible; ButtonPanel.Opacity = 1; _isPreviewing = false; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"Error in TakePhotoAsync: {ex.Message}"); } } private void RetakeButton_Click(object sender, RoutedEventArgs e) { ButtonPanel.Opacity = 0; CapturedImage.Visibility = Visibility.Collapsed; CameraPreview.Visibility = Visibility.Visible; _isPreviewing = true; } private void PrintButton_Click(object sender, RoutedEventArgs e) { // Print function to be implemented } } }
C#
복사

Code Explanation

EnterFullScreenMode: Sets the app to run in full-screen mode.
InitializeCameraAsync: Initializes the camera and starts the preview.
CameraPreview_Tapped: Executes the logic to start the countdown and take a photo when the screen is tapped.
StartCountdownAndTakePhoto: Performs a 5-second countdown and takes a photo.
TakePhotoAsync: Captures a photo and displays the captured image on the screen. Here, RenderTargetBitmap is used to capture the preview screen.
RetakeButton_Click: Returns to the preview screen when the "Retake" button is pressed.

4. Debugging and Testing

After building and running the app, clicking on the screen starts the countdown, and after the countdown, a photo is taken. The preview screen disappears, and the captured photo and buttons are displayed.

5. Summary

In this post, we implemented a photo capture function with a 5-second countdown. We displayed the captured photo and implemented the UI for retake and print functions. In the next post, we plan to enhance the app's completeness by adding a feature to combine the background with the photo.
Next time:
Creating a UWP desktop app in C# 4/5: Image composition - Combining background and photo

Read in other languages:

Support the Author:

If you enjoy my article, consider supporting me with a coffee!
Search
September 2024
Today
S
M
T
W
T
F
S