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"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" /> <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component> </component>
</project> </project>

View File

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

View File

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

View File

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

View File

@ -2,7 +2,8 @@
"AppSettings": { "AppSettings": {
"AppName": "Meine Anwendung", "AppName": "Meine Anwendung",
"Version": "1.0.0", "Version": "1.0.0",
"PictureLocation": "C:\\cambooth\\pictures" "PictureLocation": "C:\\cambooth\\pictures",
"DebugConsoleVisible": "true"
}, },
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Server=myServer;Database=myDB;User Id=myUser;Password=myPassword;" "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 System.Windows;
using CamBooth.App.Core.AppSettings; using CamBooth.App.Core.AppSettings;
@ -192,6 +193,53 @@ public class CameraService : IDisposable
throw; 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 #region API Events
@ -291,3 +339,4 @@ public class CameraService : IDisposable
#endregion #endregion
} }

View File

@ -41,8 +41,16 @@
Panel.ZIndex="1" /> Panel.ZIndex="1" />
<!-- Inhalt der dritten Zeile --> <!-- 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"> 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"/> <liveView:TimerControlRectangleAnimation x:Name="TimerControlRectangleAnimation" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Name="ButtonPanel" Background="Transparent" Panel.ZIndex="2" <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Bottom" Name="ButtonPanel" Background="Transparent" Panel.ZIndex="2"

View File

@ -1,5 +1,7 @@
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Threading;
using CamBooth.App.Core.AppSettings; using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging; using CamBooth.App.Core.Logging;
@ -29,6 +31,12 @@ public partial class MainWindow : Window
private LiveViewPage? _liveViewPage; private LiveViewPage? _liveViewPage;
private bool _isPhotoProcessRunning;
private readonly DispatcherTimer _focusStatusAnimationTimer = new() { Interval = TimeSpan.FromMilliseconds(250) };
private int _focusStatusDots;
public MainWindow( public MainWindow(
Logger logger, Logger logger,
@ -41,11 +49,16 @@ public partial class MainWindow : Window
this._pictureGalleryService = pictureGalleryService; this._pictureGalleryService = pictureGalleryService;
this._cameraService = cameraService; this._cameraService = cameraService;
InitializeComponent(); InitializeComponent();
this.SetVisibilityDebugConsole(this._isDebugConsoleVisible); this.SetVisibilityDebugConsole(_appSettings.IsDebugConsoleVisible);
this.SetVisibilityPicturePanel(this._isPicturePanelVisible); this.SetVisibilityPicturePanel(this._isPicturePanelVisible);
_ = this._pictureGalleryService.LoadThumbnailsToCache(); _ = this._pictureGalleryService.LoadThumbnailsToCache();
this.Closing += OnClosing; this.Closing += OnClosing;
TimerControlRectangleAnimation.OnTimerEllapsed += TimerControlRectangleAnimation_OnTimerEllapsed; 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($"config file loaded: '{appSettings.ConfigFileName}'");
logger.Info("MainWindow initialized"); logger.Info("MainWindow initialized");
} }
@ -65,7 +78,10 @@ public partial class MainWindow : Window
} }
finally finally
{ {
this.StopFocusStatusAnimation();
this.CaptureStatusText.Visibility = Visibility.Collapsed;
SwitchButtonAndTimerPanel(); SwitchButtonAndTimerPanel();
this._isPhotoProcessRunning = false;
} }
} }
@ -106,6 +122,11 @@ public partial class MainWindow : Window
private void SetVisibilityDebugConsole(bool visibility) private void SetVisibilityDebugConsole(bool visibility)
{ {
if (!_appSettings.IsDebugConsoleVisible)
{
return;
}
if (visibility) if (visibility)
{ {
this.DebugFrame.Navigate(new DebugConsolePage(this._logger)); 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 try
{ {
SwitchButtonAndTimerPanel();
#if DEBUG #if DEBUG
TimerControlRectangleAnimation.StartTimer(1); 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 #else
TimerControlRectangleAnimation.StartTimer(5); 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 #endif
SwitchButtonAndTimerPanel();
} }
catch (Exception exception) 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); this._logger.Error(exception.Message);
} }
} }
@ -152,4 +210,17 @@ public partial class MainWindow : Window
{ {
this.Close(); 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.)