Search
Duplicate

C#으로 UWP 데스크톱 앱 만들기 3/5: 사진 촬영 및 5초 카운트다운 기능 추가

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

시리즈

안녕하세요! 이번 포스트에서는 UWP 앱에서 5초 카운트다운 후 사진을 촬영하고 결과를 화면에 표시하는 기능을 구현해보겠습니다. 프리뷰 화면을 클릭하면 카운트다운이 시작되고, 사진이 촬영된 후에는 프리뷰가 사라지고 촬영된 사진, 다시 찍기, 인쇄 버튼이 표시됩니다.
이전 포스트에서 카메라 프리뷰 기능을 구현했으므로, 이번에는 카운트다운과 촬영 기능을 추가해 더 인터랙티브한 앱으로 발전시켜 보겠습니다.

1. 앱의 흐름 계획

사용자가 앱을 사용하면서 경험할 흐름은 다음과 같습니다:
1.
프리뷰 화면에서 사용자가 화면을 클릭하면 5초 카운트다운이 시작됩니다.
2.
카운트다운이 끝나면 사진이 촬영되고 프리뷰 화면이 사라집니다.
3.
촬영된 사진이 화면에 표시되고, 다시 찍기인쇄 버튼이 나타납니다.
4.
사용자가 "다시 찍기" 버튼을 누르면 프리뷰 화면으로 돌아가고, "인쇄" 버튼을 누르면 (인쇄 기능은 추후 추가 예정) 사진을 인쇄할 수 있습니다.

2. UI 구성

우선 UI를 구성하기 위해 MainPage.xaml을 수정합니다. 프리뷰 화면, 촬영된 사진을 표시할 이미지 컨트롤, 그리고 카운트다운을 표시할 텍스트 블록을 추가했습니다.
<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> <!-- 카메라 프리뷰 --> <CaptureElement x:Name="CameraPreview" HorizontalAlignment="Center" VerticalAlignment="Center" Width="640" Height="480" Grid.Row="0" Tapped="CameraPreview_Tapped"/> <!-- 카운트다운 텍스트 --> <TextBlock x:Name="CountdownText" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="60" Visibility="Collapsed" Grid.Row="0"/> <!-- 촬영된 사진 표시 --> <Image x:Name="CapturedImage" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Width="640" Height="480" Grid.Row="0"/> <!-- 다시 찍기 및 인쇄 버튼 --> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Opacity="0" x:Name="ButtonPanel" Grid.Row="1" Margin="0,10,0,10"> <Button Content="다시 찍기" Click="RetakeButton_Click" Margin="10"/> <Button Content="인쇄" Click="PrintButton_Click" Margin="10"/> </StackPanel> </Grid> </Page>
XML
복사

UI 설명

CaptureElement: 카메라 프리뷰 화면을 표시하는 컨트롤.
TextBlock (CountdownText): 사진 촬영 전 카운트다운을 표시합니다.
Image (CapturedImage): 촬영된 사진을 표시할 컨트롤입니다.
StackPanel (ButtonPanel): 촬영된 후 "다시 찍기" 및 "인쇄" 버튼을 표시하는 영역입니다.

3. 사진 촬영 및 카운트다운 구현

이제 MainPage.xaml.cs에서 카운트다운과 사진 촬영 기능을 구현합니다. 전체화면 모드로 전환하는 코드와 카메라 캡처를 처리하는 로직이 포함되어 있습니다.
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(); // 전체화면 모드로 전환 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) { // 인쇄 기능 구현 예정 } } }
C#
복사

코드 설명

EnterFullScreenMode: 앱이 전체 화면 모드로 실행되도록 설정합니다.
InitializeCameraAsync: 카메라를 초기화하고 프리뷰를 시작합니다.
CameraPreview_Tapped: 화면을 탭하면 카운트다운이 시작되고 사진을 촬영하는 로직을 실행합니다.
StartCountdownAndTakePhoto: 5초 동안 카운트다운을 진행하고 사진을 촬영합니다.
TakePhotoAsync: 사진을 촬영하고 캡처된 이미지를 화면에 표시합니다. 여기서는 RenderTargetBitmap을 이용해 프리뷰 화면을 캡처합니다.
RetakeButton_Click: "다시 찍기" 버튼을 누르면 프리뷰 화면으로 돌아갑니다.

4. 디버그 및 테스트

앱을 빌드하고 실행한 후, 화면을 클릭하면 카운트다운이 시작되고, 카운트다운 후 사진이 촬영되면 프리뷰 화면이 사라지고 촬영된 사진과 버튼들이 나타나야 합니다.

5. 마무리

이번 포스트에서는 5초 카운트다운 후 사진 촬영 기능을 구현하였습니다. 촬영된 사진을 표시하고, 다시 찍기와 인쇄 기능을 위한 UI까지 구현했습니다. 다음 포스트에서는 배경과 사진을 결합하는 기능을 추가하여 앱의 완성도를 높일 계획입니다.
다음 회차 예고:
C#으로 UWP 데스크톱 앱 만들기 4/5: 이미지 합성-배경과 사진 결합

다른 언어로 읽기:

Read in English:
日本語で読む:

작가 후원하기:

제 기사가 마음에 드셨다면, 커피 한 잔으로 응원해 주세요!
Search
September 2024
Today
S
M
T
W
T
F
S