kamera fokussieren während timer läuft

This commit is contained in:
iTob 2026-02-24 19:59:11 +01:00
parent 1d3064904a
commit 074f3ccb7f
9 changed files with 157 additions and 17 deletions

View File

@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -29,7 +29,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Core\Models\" />
<Folder Include="Features\" />
</ItemGroup>

View File

@ -32,7 +32,11 @@ public class AppSettingsService
}
public string? AppName => configuration["AppSettings:AppName"];
public bool IsDebugConsoleVisible => bool.Parse(configuration["AppSettings:DebugConsoleVisible"] ?? string.Empty);
public string? PictureLocation => configuration["AppSettings:PictureLocation"];
public string? ConnectionString => configuration.GetConnectionString("DefaultConnection");
public string ConfigFileName => loadedConfigFile;

View File

@ -2,7 +2,8 @@
"AppSettings": {
"AppName": "Meine Anwendung",
"Version": "1.0.0",
"PictureLocation": "C:\\tmp\\cambooth"
"PictureLocation": "C:\\tmp\\cambooth",
"DebugConsoleVisible": "true"
},
"ConnectionStrings": {
"DefaultConnection": "Server=myServer;Database=myDB;User Id=myUser;Password=myPassword;"

View File

@ -2,7 +2,8 @@
"AppSettings": {
"AppName": "Meine Anwendung",
"Version": "1.0.0",
"PictureLocation": "C:\\cambooth\\pictures"
"PictureLocation": "C:\\cambooth\\pictures",
"DebugConsoleVisible": "true"
},
"ConnectionStrings": {
"DefaultConnection": "Server=myServer;Database=myDB;User Id=myUser;Password=myPassword;"

View File

@ -1,4 +1,5 @@
using System.IO;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using CamBooth.App.Core.AppSettings;
@ -192,6 +193,53 @@ public class CameraService : IDisposable
throw;
}
}
public async Task PrepareFocusAsync(int focusTimeoutMs = 1500)
{
if (this._mainCamera is not EOSDigital.API.Camera sdkCamera)
{
await Task.Delay(200);
return;
}
var focusCompleted = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
void FocusStateChanged(EOSDigital.API.Camera sender, StateEventID eventId, int parameter)
{
if (eventId == StateEventID.AfResult)
{
focusCompleted.TrySetResult(true);
}
}
sdkCamera.StateChanged += FocusStateChanged;
try
{
await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Halfway));
var completedTask = await Task.WhenAny(focusCompleted.Task, Task.Delay(focusTimeoutMs));
if (completedTask != focusCompleted.Task)
{
this._logger.Info("Autofocus timeout reached, continuing with countdown.");
}
}
catch (Exception ex)
{
this.ReportError(ex.Message);
}
finally
{
try
{
await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.OFF));
}
catch (Exception ex)
{
this.ReportError(ex.Message);
}
sdkCamera.StateChanged -= FocusStateChanged;
}
}
#region API Events
@ -290,4 +338,5 @@ public class CameraService : IDisposable
}
#endregion
}
}

View File

@ -41,8 +41,16 @@
Panel.ZIndex="1" />
<!-- Inhalt der dritten Zeile -->
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Visibility="Hidden" Name="TimerPanel" Background="#AA000000" Panel.ZIndex="2"
<StackPanel Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Bottom" Visibility="Hidden" Name="TimerPanel" Background="#AA000000" Panel.ZIndex="2"
Margin="0 0 0 0">
<TextBlock x:Name="CaptureStatusText"
Text="Scharfstellen..."
Visibility="Collapsed"
Foreground="White"
FontSize="36"
FontWeight="Bold"
HorizontalAlignment="Center"
Margin="24 24 24 12"/>
<liveView:TimerControlRectangleAnimation x:Name="TimerControlRectangleAnimation" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Name="ButtonPanel" Background="Transparent" Panel.ZIndex="2"
@ -81,4 +89,4 @@
Panel.ZIndex="2" />
</Grid>
</Window>
</Window>

View File

@ -1,5 +1,7 @@
using System.ComponentModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;
@ -28,6 +30,12 @@ public partial class MainWindow : Window
private bool _isPicturePanelVisible = false;
private LiveViewPage? _liveViewPage;
private bool _isPhotoProcessRunning;
private readonly DispatcherTimer _focusStatusAnimationTimer = new() { Interval = TimeSpan.FromMilliseconds(250) };
private int _focusStatusDots;
public MainWindow(
@ -41,11 +49,16 @@ public partial class MainWindow : Window
this._pictureGalleryService = pictureGalleryService;
this._cameraService = cameraService;
InitializeComponent();
this.SetVisibilityDebugConsole(this._isDebugConsoleVisible);
this.SetVisibilityDebugConsole(_appSettings.IsDebugConsoleVisible);
this.SetVisibilityPicturePanel(this._isPicturePanelVisible);
_ = this._pictureGalleryService.LoadThumbnailsToCache();
this.Closing += OnClosing;
TimerControlRectangleAnimation.OnTimerEllapsed += TimerControlRectangleAnimation_OnTimerEllapsed;
this._focusStatusAnimationTimer.Tick += (_, _) =>
{
this._focusStatusDots = (this._focusStatusDots + 1) % 4;
this.CaptureStatusText.Text = $"Scharfstellen{new string('.', this._focusStatusDots)}";
};
logger.Info($"config file loaded: '{appSettings.ConfigFileName}'");
logger.Info("MainWindow initialized");
}
@ -65,7 +78,10 @@ public partial class MainWindow : Window
}
finally
{
this.StopFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Collapsed;
SwitchButtonAndTimerPanel();
this._isPhotoProcessRunning = false;
}
}
@ -106,6 +122,11 @@ public partial class MainWindow : Window
private void SetVisibilityDebugConsole(bool visibility)
{
if (!_appSettings.IsDebugConsoleVisible)
{
return;
}
if (visibility)
{
this.DebugFrame.Navigate(new DebugConsolePage(this._logger));
@ -119,19 +140,56 @@ public partial class MainWindow : Window
}
private void StartTakePhotoProcess(object sender, RoutedEventArgs e)
private async void StartTakePhotoProcess(object sender, RoutedEventArgs e)
{
if (this._isPhotoProcessRunning)
{
return;
}
this._isPhotoProcessRunning = true;
try
{
#if DEBUG
TimerControlRectangleAnimation.StartTimer(1);
#else
TimerControlRectangleAnimation.StartTimer(5);
#endif
SwitchButtonAndTimerPanel();
#if DEBUG
TimerControlRectangleAnimation.StartTimer(2);
this.StartFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Visible;
await Task.Delay(TimeSpan.FromSeconds(1));
if (!this._isPhotoProcessRunning)
{
return;
}
await this._cameraService.PrepareFocusAsync(focusTimeoutMs: 1000);
this.StopFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Collapsed;
#else
TimerControlRectangleAnimation.StartTimer(5);
this.StartFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Visible;
await Task.Delay(TimeSpan.FromSeconds(2));
if (!this._isPhotoProcessRunning)
{
return;
}
await this._cameraService.PrepareFocusAsync(focusTimeoutMs: 3000);
this.StopFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Collapsed;
#endif
}
catch (Exception exception)
{
this._isPhotoProcessRunning = false;
this.StopFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Collapsed;
if (this.TimerPanel.Visibility == Visibility.Visible)
{
SwitchButtonAndTimerPanel();
}
this._logger.Error(exception.Message);
}
}
@ -152,4 +210,17 @@ public partial class MainWindow : Window
{
this.Close();
}
}
private void StartFocusStatusAnimation()
{
this._focusStatusDots = 0;
this.CaptureStatusText.Text = "Scharfstellen";
this._focusStatusAnimationTimer.Start();
}
private void StopFocusStatusAnimation()
{
this._focusStatusAnimationTimer.Stop();
this._focusStatusDots = 0;
}
}

View File

@ -0,0 +1,8 @@
- Rotate Flick Picture 180°
- Printer anschließen
- Galerie schließen
- Debug Window schließen
- Kiosk Modus einrichten
- Energiesparmodus abschalten
- Starbildschirm mit freundlicher Begrüßung, kurzer Erklärung, und viel Spaß wünschen mit der FotoCam
- Verschiedene Hinweise anzeigen beim Fotofrafieren (lächeln, Hasensohren, Zunge raus, Grimasse, usw.)