wip
This commit is contained in:
parent
3cd16ac714
commit
e06aede5cd
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
8
src/CamBooth/CamBooth.App/App.xaml
Normal file
8
src/CamBooth/CamBooth.App/App.xaml
Normal file
@ -0,0 +1,8 @@
|
||||
<Application x:Class="CamBooth.App.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CamBooth.App">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
39
src/CamBooth/CamBooth.App/App.xaml.cs
Normal file
39
src/CamBooth/CamBooth.App/App.xaml.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
using CamBooth.App.Core.Logging;
|
||||
using CamBooth.App.LiveView;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace CamBooth.App;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
private IServiceProvider _serviceProvider;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
ConfigureServices(services);
|
||||
|
||||
_serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
|
||||
mainWindow.Show();
|
||||
}
|
||||
|
||||
private void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// Register your services and view models here
|
||||
services.AddTransient<MainWindow>();
|
||||
services.AddTransient<LiveViewPage>();
|
||||
services.AddSingleton<Logger>();
|
||||
}
|
||||
}
|
||||
10
src/CamBooth/CamBooth.App/AssemblyInfo.cs
Normal file
10
src/CamBooth/CamBooth.App/AssemblyInfo.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
32
src/CamBooth/CamBooth.App/CamBooth.App.csproj
Normal file
32
src/CamBooth/CamBooth.App/CamBooth.App.csproj
Normal file
@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EDSDKLib\EDSDKLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Core\Models\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
9
src/CamBooth/CamBooth.App/Core/Logging/Logger.cs
Normal file
9
src/CamBooth/CamBooth.App/Core/Logging/Logger.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace CamBooth.App.Core.Logging;
|
||||
|
||||
public class Logger
|
||||
{
|
||||
public void LogInfo(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
12
src/CamBooth/CamBooth.App/DebugConsole/DebugConsolePage.xaml
Normal file
12
src/CamBooth/CamBooth.App/DebugConsole/DebugConsolePage.xaml
Normal file
@ -0,0 +1,12 @@
|
||||
<Page x:Class="CamBooth.App.DebugConsole.DebugConsolePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:CamBooth.App.DebugConsole"
|
||||
mc:Ignorable="d"
|
||||
Title="DebugConsolePage" Height="100" Width="800">
|
||||
<Grid>
|
||||
<TextBlock>Debug Console</TextBlock>
|
||||
</Grid>
|
||||
</Page>
|
||||
@ -0,0 +1,11 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace CamBooth.App.DebugConsole;
|
||||
|
||||
public partial class DebugConsolePage : Page
|
||||
{
|
||||
public DebugConsolePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
14
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml
Normal file
14
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml
Normal file
@ -0,0 +1,14 @@
|
||||
<Page x:Class="CamBooth.App.LiveView.LiveViewPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:CamBooth.App.LiveView"
|
||||
mc:Ignorable="d"
|
||||
Title="LiveViewPage" Height="550" Width="780"
|
||||
Background="PaleVioletRed">
|
||||
<Grid>
|
||||
<TextBlock>LiveView CamBooth</TextBlock>
|
||||
<Canvas x:Name="LVCanvas" Background="LightGray" />
|
||||
</Grid>
|
||||
</Page>
|
||||
231
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml.cs
Normal file
231
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml.cs
Normal file
@ -0,0 +1,231 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
using EOSDigital.API;
|
||||
using EOSDigital.SDK;
|
||||
|
||||
namespace CamBooth.App.LiveView;
|
||||
|
||||
public partial class LiveViewPage : Page
|
||||
{
|
||||
CanonAPI APIHandler;
|
||||
|
||||
Camera MainCamera;
|
||||
|
||||
CameraValue[] AvList;
|
||||
|
||||
CameraValue[] TvList;
|
||||
|
||||
CameraValue[] ISOList;
|
||||
|
||||
List<Camera> CamList;
|
||||
|
||||
bool IsInit = false;
|
||||
|
||||
int BulbTime = 30;
|
||||
|
||||
ImageBrush bgbrush = new ImageBrush();
|
||||
|
||||
Action<BitmapImage> SetImageAction;
|
||||
|
||||
int ErrCount;
|
||||
|
||||
object ErrLock = new object();
|
||||
|
||||
|
||||
public LiveViewPage()
|
||||
{
|
||||
try
|
||||
{
|
||||
InitializeComponent();
|
||||
APIHandler = new CanonAPI();
|
||||
APIHandler.CameraAdded += APIHandler_CameraAdded;
|
||||
ErrorHandler.SevereErrorHappened += ErrorHandler_SevereErrorHappened;
|
||||
ErrorHandler.NonSevereErrorHappened += ErrorHandler_NonSevereErrorHappened;
|
||||
//SavePathTextBox.Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "RemotePhoto");
|
||||
SetImageAction = (BitmapImage img) => { bgbrush.ImageSource = img; };
|
||||
RefreshCamera();
|
||||
IsInit = true;
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{
|
||||
ReportError("Canon DLLs not found!", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void CloseSession()
|
||||
{
|
||||
MainCamera.CloseSession();
|
||||
// AvCoBox.Items.Clear();
|
||||
// TvCoBox.Items.Clear();
|
||||
// ISOCoBox.Items.Clear();
|
||||
// SettingsGroupBox.IsEnabled = false;
|
||||
// LiveViewGroupBox.IsEnabled = false;
|
||||
// SessionButton.Content = "Open Session";
|
||||
// SessionLabel.Content = "No open session";
|
||||
// StarLVButton.Content = "Start LV";
|
||||
}
|
||||
|
||||
private void RefreshCamera()
|
||||
{
|
||||
// CameraListBox.Items.Clear();
|
||||
CamList = APIHandler.GetCameraList();
|
||||
// foreach (Camera cam in CamList) CameraListBox.Items.Add(cam.DeviceName);
|
||||
// if (MainCamera?.SessionOpen == true) CameraListBox.SelectedIndex = CamList.FindIndex(t => t.ID == MainCamera.ID);
|
||||
// else if (CamList.Count > 0) CameraListBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void OpenSession()
|
||||
{
|
||||
|
||||
MainCamera = CamList[0];
|
||||
MainCamera.OpenSession();
|
||||
MainCamera.LiveViewUpdated += MainCamera_LiveViewUpdated;
|
||||
MainCamera.ProgressChanged += MainCamera_ProgressChanged;
|
||||
MainCamera.StateChanged += MainCamera_StateChanged;
|
||||
MainCamera.DownloadReady += MainCamera_DownloadReady;
|
||||
|
||||
|
||||
//SessionLabel.Content = MainCamera.DeviceName;
|
||||
AvList = MainCamera.GetSettingsList(PropertyID.Av);
|
||||
TvList = MainCamera.GetSettingsList(PropertyID.Tv);
|
||||
ISOList = MainCamera.GetSettingsList(PropertyID.ISO);
|
||||
// foreach (var Av in AvList) AvCoBox.Items.Add(Av.StringValue);
|
||||
// foreach (var Tv in TvList) TvCoBox.Items.Add(Tv.StringValue);
|
||||
// foreach (var ISO in ISOList) ISOCoBox.Items.Add(ISO.StringValue);
|
||||
// AvCoBox.SelectedIndex = AvCoBox.Items.IndexOf(AvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Av)).StringValue);
|
||||
// TvCoBox.SelectedIndex = TvCoBox.Items.IndexOf(TvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Tv)).StringValue);
|
||||
// ISOCoBox.SelectedIndex = ISOCoBox.Items.IndexOf(ISOValues.GetValue(MainCamera.GetInt32Setting(PropertyID.ISO)).StringValue);
|
||||
// SettingsGroupBox.IsEnabled = true;
|
||||
// LiveViewGroupBox.IsEnabled = true;
|
||||
|
||||
}
|
||||
|
||||
private void ReportError(string message, bool lockdown)
|
||||
{
|
||||
int errc;
|
||||
lock (ErrLock) { errc = ++ErrCount; }
|
||||
|
||||
if (lockdown) EnableUI(false);
|
||||
|
||||
if (errc < 4) MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
else if (errc == 4) MessageBox.Show("Many errors happened!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
|
||||
lock (ErrLock) { ErrCount--; }
|
||||
}
|
||||
|
||||
private void EnableUI(bool enable)
|
||||
{
|
||||
if (!Dispatcher.CheckAccess()) Dispatcher.Invoke((Action)delegate { EnableUI(enable); });
|
||||
else
|
||||
{
|
||||
// SettingsGroupBox.IsEnabled = enable;
|
||||
// InitGroupBox.IsEnabled = enable;
|
||||
// LiveViewGroupBox.IsEnabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
#region API Events
|
||||
|
||||
private void APIHandler_CameraAdded(CanonAPI sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void MainCamera_StateChanged(Camera sender, StateEventID eventID, int parameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (eventID == StateEventID.Shutdown && IsInit)
|
||||
{
|
||||
Dispatcher.Invoke((Action)delegate { CloseSession(); });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void MainCamera_ProgressChanged(object sender, int progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
//MainProgressBar.Dispatcher.Invoke((Action)delegate { MainProgressBar.Value = progress; });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void MainCamera_LiveViewUpdated(Camera sender, Stream img)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (WrapStream s = new WrapStream(img))
|
||||
{
|
||||
img.Position = 0;
|
||||
BitmapImage EvfImage = new BitmapImage();
|
||||
EvfImage.BeginInit();
|
||||
EvfImage.StreamSource = s;
|
||||
EvfImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
EvfImage.EndInit();
|
||||
EvfImage.Freeze();
|
||||
Application.Current.Dispatcher.BeginInvoke(SetImageAction, EvfImage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void MainCamera_DownloadReady(Camera sender, DownloadInfo Info)
|
||||
{
|
||||
try
|
||||
{
|
||||
string dir = null;
|
||||
//SavePathTextBox.Dispatcher.Invoke((Action)delegate { dir = SavePathTextBox.Text; });
|
||||
sender.DownloadFile(Info, dir);
|
||||
//MainProgressBar.Dispatcher.Invoke((Action)delegate { MainProgressBar.Value = 0; });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ErrorHandler_NonSevereErrorHappened(object sender, ErrorCode ex)
|
||||
{
|
||||
ReportError($"SDK Error code: {ex} ({((int)ex).ToString("X")})", false);
|
||||
}
|
||||
|
||||
|
||||
private void ErrorHandler_SevereErrorHappened(object sender, Exception ex)
|
||||
{
|
||||
ReportError(ex.Message, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
120
src/CamBooth/CamBooth.App/LiveView/WrappingStream.cs
Normal file
120
src/CamBooth/CamBooth.App/LiveView/WrappingStream.cs
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace CamBooth.App.LiveView
|
||||
{
|
||||
/// <summary>
|
||||
/// A stream that does nothing more but wrap another stream (needed for a WPF memory leak)
|
||||
/// </summary>
|
||||
public sealed class WrapStream : Stream
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports reading.
|
||||
/// </summary>
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return this.Base.CanRead; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports seeking.
|
||||
/// </summary>
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return this.Base.CanSeek; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports writing.
|
||||
/// </summary>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return this.Base.CanWrite; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the length in bytes of the stream.
|
||||
/// </summary>
|
||||
public override long Length
|
||||
{
|
||||
get { return this.Base.Length; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the position within the current stream.
|
||||
/// </summary>
|
||||
public override long Position
|
||||
{
|
||||
get { return this.Base.Position; }
|
||||
set { this.Base.Position = value; }
|
||||
}
|
||||
|
||||
private Stream Base;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="WrapStream"/> class.
|
||||
/// </summary>
|
||||
/// <param name="inStream">The stream that gets wrapped</param>
|
||||
public WrapStream(Stream inStream)
|
||||
{
|
||||
this.Base = inStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a sequence of bytes from the current stream and advances
|
||||
/// the position within the stream by the number of bytes read.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||
/// byte array with the values between offset and (offset + count - 1) replaced
|
||||
/// by the bytes read from the current source.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||
/// from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>The total number of bytes read into the buffer. This can be less than the
|
||||
/// number of bytes requested if that many bytes are not currently available,
|
||||
/// or zero (0) if the end of the stream has been reached.</returns>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return this.Base.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, writes a sequence of bytes to the current
|
||||
/// stream and advances the current position within this stream by the number
|
||||
/// of bytes written.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the
|
||||
/// current stream.</param>
|
||||
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
this.Base.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sets the position within the current stream.
|
||||
/// </summary>
|
||||
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||
/// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used
|
||||
/// to obtain the new position.</param>
|
||||
/// <returns>The new position within the current stream.</returns>
|
||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||
{
|
||||
return this.Base.Seek(offset, origin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all buffers for this stream and causes any buffered data to be written to the underlying device.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
this.Base.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the length of the current stream.
|
||||
/// </summary>
|
||||
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
this.Base.SetLength(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/CamBooth/CamBooth.App/MainWindow.xaml
Normal file
43
src/CamBooth/CamBooth.App/MainWindow.xaml
Normal file
@ -0,0 +1,43 @@
|
||||
<Window x:Class="CamBooth.App.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:CamBooth.App"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="650" Width="800">
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- Erste Zeile (Auto-Höhe) -->
|
||||
<RowDefinition Height="*"/> <!-- Zweite Zeile (flexibler Platz) -->
|
||||
<RowDefinition Height="Auto"/> <!-- Dritte Zeile (Auto-Höhe) -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Inhalt der ersten Zeile -->
|
||||
<Frame Grid.Row="0"
|
||||
x:Name="MainFrame"
|
||||
NavigationUIVisibility="Hidden"
|
||||
HorizontalAlignment="Center"
|
||||
Background="LightBlue"
|
||||
VerticalAlignment="Center"
|
||||
Panel.ZIndex="0" />
|
||||
|
||||
<!-- Inhalt der zweiten Zeile (nimmt den verbleibenden Platz ein) -->
|
||||
<Frame Grid.Row="1"
|
||||
x:Name="DebugFrame"
|
||||
NavigationUIVisibility="Hidden"
|
||||
HorizontalAlignment="Center"
|
||||
Height="100"
|
||||
Background="LightGreen"
|
||||
VerticalAlignment="Bottom"
|
||||
Panel.ZIndex="1" />
|
||||
|
||||
<!-- Inhalt der dritten Zeile -->
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Button Content="Start" Click="NavToLiveView" Width="200" Background="LightCoral" Height="50" VerticalAlignment="Bottom"/>
|
||||
<Button Content="Hide Debug" Click="ToggleDebugConsole" Width="200" Background="LightCoral" Height="50" VerticalAlignment="Bottom"/>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
51
src/CamBooth/CamBooth.App/MainWindow.xaml.cs
Normal file
51
src/CamBooth/CamBooth.App/MainWindow.xaml.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
using CamBooth.App.Core.Logging;
|
||||
using CamBooth.App.DebugConsole;
|
||||
using CamBooth.App.LiveView;
|
||||
|
||||
namespace CamBooth.App;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
private bool _isDebugConsoleVisible;
|
||||
|
||||
public MainWindow(Logger logger)
|
||||
{
|
||||
this._logger = logger;
|
||||
InitializeComponent();
|
||||
logger.LogInfo("MainWindow initialized");
|
||||
ToggleDebugConsole();
|
||||
}
|
||||
|
||||
private void NavToLiveView(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MainFrame.Navigate(new LiveViewPage());
|
||||
}
|
||||
|
||||
private void ToggleDebugConsole(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.ToggleDebugConsole();
|
||||
}
|
||||
|
||||
private void ToggleDebugConsole()
|
||||
{
|
||||
if (_isDebugConsoleVisible)
|
||||
{
|
||||
this.DebugFrame.ClearValue(Frame.ContentProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DebugFrame.Navigate(new DebugConsolePage());
|
||||
}
|
||||
|
||||
this._isDebugConsoleVisible = !this._isDebugConsoleVisible;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamBooth.App", "CamBooth.App\CamBooth.App.csproj", "{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDSDKLib", "EDSDKLib\EDSDKLib.csproj", "{15E99248-6161-46A4-9183-609CA62406A6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
12
src/CamBooth/CamBooth.sln.DotSettings.user
Normal file
12
src/CamBooth/CamBooth.sln.DotSettings.user
Normal file
@ -0,0 +1,12 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPDLL_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPLibCom_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPRSC_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CEDSDK_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CEdsImage_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CMlib_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CUcs32P_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AApplication_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6665f2e3e843578225e3796b83c5342a58c3f72bfef19eeee7aa90d157d4949_003FApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fbd1d5c50194fea68ff3559c160230b0ab50f5acf4ce3061bffd6d62958e2182_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0713c794b56e4feca091d5981a6f5967f60930_003Fc8_003F61b7e802_003FWindow_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd0db11e55b76dc7f234163f6cee32b297b8ddb591fb0b5cbad1b46ed17343e18_003FWindow_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
1569
src/CamBooth/EDSDKLib/API/Base/Camera.cs
Normal file
1569
src/CamBooth/EDSDKLib/API/Base/Camera.cs
Normal file
File diff suppressed because it is too large
Load Diff
337
src/CamBooth/EDSDKLib/API/Base/CanonAPI.cs
Normal file
337
src/CamBooth/EDSDKLib/API/Base/CanonAPI.cs
Normal file
@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using EOSDigital.SDK;
|
||||
using Size = EOSDigital.SDK.Size;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles camera connections
|
||||
/// </summary>
|
||||
public class CanonAPI : IDisposable
|
||||
{
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Fires if a new camera is added
|
||||
/// </summary>
|
||||
public event CameraAddedHandler CameraAdded;
|
||||
/// <summary>
|
||||
/// The SDK camera added delegate
|
||||
/// </summary>
|
||||
protected static SDKCameraAddedHandler CameraAddedEvent;
|
||||
|
||||
private ErrorCode CanonAPI_CameraAddedEvent(IntPtr inContext)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem((state) => CameraAdded?.Invoke(this));
|
||||
return ErrorCode.OK;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Variables
|
||||
|
||||
/// <summary>
|
||||
/// States if the SDK is initialized or not
|
||||
/// </summary>
|
||||
public static bool IsSDKInitialized
|
||||
{
|
||||
get { return _IsSDKInitialized; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The main SDK thread where the event loop runs
|
||||
/// </summary>
|
||||
protected static STAThread MainThread;
|
||||
|
||||
/// <summary>
|
||||
/// Field for the public <see cref="IsSDKInitialized"/> property
|
||||
/// </summary>
|
||||
private static bool _IsSDKInitialized;
|
||||
/// <summary>
|
||||
/// States if the instance is disposed or not
|
||||
/// </summary>
|
||||
private bool IsDisposed;
|
||||
/// <summary>
|
||||
/// Number of instances of this class
|
||||
/// </summary>
|
||||
private static int RefCount = 0;
|
||||
/// <summary>
|
||||
/// Object to lock on to safely de- and increment the <see cref="RefCount"/> value
|
||||
/// </summary>
|
||||
private static readonly object InitLock = new object();
|
||||
/// <summary>
|
||||
/// List of currently connected cameras (since the last time GetCameraList got called)
|
||||
/// </summary>
|
||||
private static List<Camera> CurrentCameras = new List<Camera>();
|
||||
/// <summary>
|
||||
/// Object to lock on to safely add/remove cameras from the <see cref="CurrentCameras"/> list
|
||||
/// </summary>
|
||||
private static readonly object CameraLock = new object();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Init/Dispose
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the SDK
|
||||
/// </summary>
|
||||
public CanonAPI()
|
||||
: this(false)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the SDK
|
||||
/// </summary>
|
||||
/// <param name="useCallingThread">If true, the calling thread will be used as SDK main thread;
|
||||
/// if false, a separate thread will be created</param>
|
||||
public CanonAPI(bool useCallingThread)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Ensure that only one caller at a time can increase the counter
|
||||
lock (InitLock)
|
||||
{
|
||||
//If no instance exists yet, initialize everything
|
||||
if (RefCount == 0)
|
||||
{
|
||||
if (useCallingThread)
|
||||
{
|
||||
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
|
||||
throw new ThreadStateException("Calling thread must be in STA");
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK());
|
||||
}
|
||||
else
|
||||
{
|
||||
//Trying to trigger DllNotFoundException so it's not thrown
|
||||
//in the event loop on a different thread:
|
||||
CanonSDK.EdsRelease(IntPtr.Zero);
|
||||
|
||||
//Start the main thread where SDK will run on
|
||||
MainThread = new ApiThread();
|
||||
MainThread.Start();
|
||||
//Initialize the SDK on the main thread
|
||||
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK()));
|
||||
}
|
||||
|
||||
CanonSDK.InitializeVersion();
|
||||
//Subscribe to the CameraAdded event
|
||||
CameraAddedEvent = new SDKCameraAddedHandler(CanonAPI_CameraAddedEvent);
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraAddedHandler(CameraAddedEvent, IntPtr.Zero));
|
||||
_IsSDKInitialized = true;
|
||||
}
|
||||
RefCount++;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
IsDisposed = true;
|
||||
if (MainThread?.IsRunning == true) MainThread.Shutdown();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
~CanonAPI()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the SDK and disposes resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the SDK and disposes resources
|
||||
/// </summary>
|
||||
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
|
||||
protected virtual void Dispose(bool managed)
|
||||
{
|
||||
//Ensure that only one caller at a time can decrease the counter
|
||||
lock (InitLock)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
//If it's the last instance, release everything
|
||||
if (RefCount == 1)
|
||||
{
|
||||
_IsSDKInitialized = false;//Set beforehand because if an error happens, the SDK will be in an unstable state anyway
|
||||
|
||||
//Remove event handler for the CameraAdded event
|
||||
ErrorCode err = CanonSDK.EdsSetCameraAddedHandler(null, IntPtr.Zero);
|
||||
if (managed)
|
||||
{
|
||||
ErrorHandler.CheckError(this, err);
|
||||
//Dispose all the connected cameras
|
||||
CurrentCameras.ForEach(t => t.Dispose());
|
||||
}
|
||||
//Terminate the SDK
|
||||
if (MainThread?.IsRunning == true) err = MainThread.Invoke(() => { return CanonSDK.EdsTerminateSDK(); });
|
||||
//Close the main thread
|
||||
if (MainThread?.IsRunning == true) MainThread.Shutdown();
|
||||
if (managed) ErrorHandler.CheckError(this, err);
|
||||
}
|
||||
RefCount--;
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all cameras connected to the host.
|
||||
/// <para>If a camera has been connected previously, the same instance of the class is returned.</para>
|
||||
/// </summary>
|
||||
/// <returns>A list of connected cameras</returns>
|
||||
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
|
||||
/// <exception cref="SDKException">An SDK call failed</exception>
|
||||
public List<Camera> GetCameraList()
|
||||
{
|
||||
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
|
||||
|
||||
//Ensure that only one caller at a time can access the camera list
|
||||
lock (CameraLock)
|
||||
{
|
||||
//Get a list of camera pointers
|
||||
IEnumerable<IntPtr> ptrList = GetCameraPointerList();
|
||||
List<Camera> camList = new List<Camera>();
|
||||
|
||||
//Find cameras that were connected before and add new ones
|
||||
foreach (var ptr in ptrList)
|
||||
{
|
||||
var oldCam = CurrentCameras.FirstOrDefault(t => t.Reference == ptr);
|
||||
if (oldCam != null && !oldCam.IsDisposed) camList.Add(oldCam); //Pointer exists already so we reuse it
|
||||
else camList.Add(new Camera(ptr)); //Pointer does not exists yet, so we add it
|
||||
}
|
||||
|
||||
//Ensure that cameras not connected anymore are disposed properly
|
||||
var oldCameras = CurrentCameras.Where(t => !ptrList.Any(u => u == t.Reference));
|
||||
foreach (var cam in oldCameras) { if (!cam.IsDisposed) cam.Dispose(); }
|
||||
|
||||
CurrentCameras.Clear();
|
||||
CurrentCameras.AddRange(camList);
|
||||
return camList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all pointer of the cameras connected to the host
|
||||
/// </summary>
|
||||
/// <returns>A list of connected cameras as pointer</returns>
|
||||
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
|
||||
/// <exception cref="SDKException">An SDK call failed</exception>
|
||||
protected IEnumerable<IntPtr> GetCameraPointerList()
|
||||
{
|
||||
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
|
||||
|
||||
IntPtr camlist;
|
||||
//Get camera list
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetCameraList(out camlist));
|
||||
|
||||
//Get number of connected cameras
|
||||
int camCount;
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(camlist, out camCount));
|
||||
List<IntPtr> ptrList = new List<IntPtr>();
|
||||
for (int i = 0; i < camCount; i++)
|
||||
{
|
||||
//Get camera pointer
|
||||
IntPtr cptr;
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(camlist, i, out cptr));
|
||||
ptrList.Add(cptr);
|
||||
}
|
||||
//Release the list
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsRelease(camlist));
|
||||
return ptrList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a thumbnail from a Raw or Jpg image
|
||||
/// </summary>
|
||||
/// <param name="filepath">Path to the image file</param>
|
||||
/// <returns>A <see cref="Bitmap"/> thumbnail from the provided image file</returns>
|
||||
public Bitmap GetFileThumb(string filepath)
|
||||
{
|
||||
//create a file stream to given file
|
||||
using (var stream = new SDKStream(filepath, FileCreateDisposition.OpenExisting, FileAccess.Read))
|
||||
{
|
||||
//Create a thumbnail Bitmap from the stream
|
||||
return GetImage(stream.Reference, ImageSource.Thumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Bitmap"/> from an EDSDK pointer to an image (Jpg or Raw)
|
||||
/// </summary>
|
||||
/// <param name="imgStream">Stream pointer to the image</param>
|
||||
/// <param name="imageSource">The result image type</param>
|
||||
/// <returns>A <see cref="Bitmap"/> image from the given stream pointer</returns>
|
||||
protected Bitmap GetImage(IntPtr imgStream, ImageSource imageSource)
|
||||
{
|
||||
IntPtr imgRef = IntPtr.Zero;
|
||||
IntPtr streamPointer = IntPtr.Zero;
|
||||
ImageInfo imageInfo;
|
||||
|
||||
try
|
||||
{
|
||||
//create reference and get image info
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsCreateImageRef(imgStream, out imgRef));
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetImageInfo(imgRef, imageSource, out imageInfo));
|
||||
|
||||
Size outputSize = new Size();
|
||||
outputSize.Width = imageInfo.EffectiveRect.Width;
|
||||
outputSize.Height = imageInfo.EffectiveRect.Height;
|
||||
//calculate amount of data
|
||||
int datalength = outputSize.Height * outputSize.Width * 3;
|
||||
//create buffer that stores the image
|
||||
byte[] buffer = new byte[datalength];
|
||||
//create a stream to the buffer
|
||||
using (var stream = new SDKStream(buffer))
|
||||
{
|
||||
//load image into the buffer
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetImage(imgRef, imageSource, TargetImageType.RGB, imageInfo.EffectiveRect, outputSize, stream.Reference));
|
||||
|
||||
//make BGR from RGB (System.Drawing (i.e. GDI+) uses BGR)
|
||||
unsafe
|
||||
{
|
||||
byte tmp;
|
||||
fixed (byte* pix = buffer)
|
||||
{
|
||||
for (long i = 0; i < datalength; i += 3)
|
||||
{
|
||||
tmp = pix[i]; //Save B value
|
||||
pix[i] = pix[i + 2]; //Set B value with R value
|
||||
pix[i + 2] = tmp; //Set R value with B value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Get pointer to stream data
|
||||
ErrorHandler.CheckError(this, CanonSDK.EdsGetPointer(stream.Reference, out streamPointer));
|
||||
//Create bitmap with the data in the buffer
|
||||
return new Bitmap(outputSize.Width, outputSize.Height, datalength, PixelFormat.Format24bppRgb, streamPointer);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
//Release all data
|
||||
if (imgStream != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgStream));
|
||||
if (imgRef != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgRef));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
25
src/CamBooth/EDSDKLib/API/Helper/ApiThread.cs
Normal file
25
src/CamBooth/EDSDKLib/API/Helper/ApiThread.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using EOSDigital.SDK;
|
||||
using System.Threading;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
internal sealed class ApiThread : STAThread
|
||||
{
|
||||
protected override void WaitForNotification()
|
||||
{
|
||||
lock (threadLock1)
|
||||
{
|
||||
while (block1 && IsRunning)
|
||||
{
|
||||
Monitor.Wait(threadLock1, 0);
|
||||
lock (ExecLock)
|
||||
{
|
||||
CanonSDK.EdsGetEvent();
|
||||
Monitor.Wait(ExecLock, 40);
|
||||
}
|
||||
}
|
||||
block1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
282
src/CamBooth/EDSDKLib/API/Helper/CameraValue.cs
Normal file
282
src/CamBooth/EDSDKLib/API/Helper/CameraValue.cs
Normal file
@ -0,0 +1,282 @@
|
||||
using EOSDigital.SDK;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores a camera value
|
||||
/// </summary>
|
||||
public class CameraValue
|
||||
{
|
||||
/// <summary>
|
||||
/// The value as a string
|
||||
/// </summary>
|
||||
public string StringValue { get; protected set; }
|
||||
/// <summary>
|
||||
/// The value as an UInt
|
||||
/// </summary>
|
||||
public int IntValue { get; protected set; }
|
||||
/// <summary>
|
||||
/// The value as a double
|
||||
/// </summary>
|
||||
public double DoubleValue { get; protected set; }
|
||||
/// <summary>
|
||||
/// The property ID of this value
|
||||
/// </summary>
|
||||
public PropertyID ValueType { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="CameraValue"/> class
|
||||
/// </summary>
|
||||
protected CameraValue()
|
||||
{
|
||||
ValueType = PropertyID.Unknown;
|
||||
StringValue = "N/A";
|
||||
IntValue = unchecked((int)0xFFFFFFFF);
|
||||
DoubleValue = 0.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new camera value
|
||||
/// </summary>
|
||||
/// <param name="Value">The value as a string</param>
|
||||
/// <param name="ValueType">The property ID of the value</param>
|
||||
public CameraValue(string Value, PropertyID ValueType)
|
||||
: this()
|
||||
{
|
||||
this.ValueType = ValueType;
|
||||
StringValue = Value;
|
||||
switch (ValueType)
|
||||
{
|
||||
case PropertyID.Av:
|
||||
IntValue = AvValues.GetValue(Value).IntValue;
|
||||
DoubleValue = AvValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.Tv:
|
||||
IntValue = TvValues.GetValue(Value).IntValue;
|
||||
DoubleValue = TvValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ISO:
|
||||
IntValue = ISOValues.GetValue(Value).IntValue;
|
||||
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ColorTemperature:
|
||||
int utmp;
|
||||
IntValue = (int.TryParse(Value, out utmp)) ? utmp : 5600;
|
||||
DoubleValue = utmp;
|
||||
break;
|
||||
case PropertyID.AEMode:
|
||||
IntValue = AEModeValues.GetValue(Value).IntValue;
|
||||
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.MeteringMode:
|
||||
IntValue = MeteringModeValues.GetValue(Value).IntValue;
|
||||
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ExposureCompensation:
|
||||
IntValue = ExpCompValues.GetValue(Value).IntValue;
|
||||
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new camera value
|
||||
/// </summary>
|
||||
/// <param name="Value">The value as an uint</param>
|
||||
/// <param name="ValueType">The property ID of the value</param>
|
||||
public CameraValue(int Value, PropertyID ValueType)
|
||||
: this()
|
||||
{
|
||||
this.ValueType = ValueType;
|
||||
IntValue = Value;
|
||||
switch (ValueType)
|
||||
{
|
||||
case PropertyID.Av:
|
||||
StringValue = AvValues.GetValue(Value).StringValue;
|
||||
DoubleValue = AvValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.Tv:
|
||||
StringValue = TvValues.GetValue(Value).StringValue;
|
||||
DoubleValue = TvValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ISO:
|
||||
StringValue = ISOValues.GetValue(Value).StringValue;
|
||||
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ColorTemperature:
|
||||
StringValue = Value.ToString();
|
||||
DoubleValue = Value;
|
||||
break;
|
||||
case PropertyID.AEMode:
|
||||
StringValue = AEModeValues.GetValue(Value).StringValue;
|
||||
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.MeteringMode:
|
||||
StringValue = MeteringModeValues.GetValue(Value).StringValue;
|
||||
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
case PropertyID.ExposureCompensation:
|
||||
StringValue = ExpCompValues.GetValue(Value).StringValue;
|
||||
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new camera value
|
||||
/// </summary>
|
||||
/// <param name="Value">The value as a double</param>
|
||||
/// <param name="ValueType">The property ID of the value</param>
|
||||
public CameraValue(double Value, PropertyID ValueType)
|
||||
: this()
|
||||
{
|
||||
this.ValueType = ValueType;
|
||||
DoubleValue = Value;
|
||||
switch (ValueType)
|
||||
{
|
||||
case PropertyID.Av:
|
||||
StringValue = AvValues.GetValue(Value).StringValue;
|
||||
IntValue = AvValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
case PropertyID.Tv:
|
||||
StringValue = TvValues.GetValue(Value).StringValue;
|
||||
IntValue = TvValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
case PropertyID.ISO:
|
||||
StringValue = ISOValues.GetValue(Value).StringValue;
|
||||
IntValue = ISOValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
case PropertyID.ColorTemperature:
|
||||
StringValue = Value.ToString("F0");
|
||||
IntValue = (int)Value;
|
||||
break;
|
||||
case PropertyID.AEMode:
|
||||
StringValue = AEModeValues.GetValue(Value).StringValue;
|
||||
IntValue = AEModeValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
case PropertyID.MeteringMode:
|
||||
StringValue = MeteringModeValues.GetValue(Value).StringValue;
|
||||
IntValue = MeteringModeValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
case PropertyID.ExposureCompensation:
|
||||
StringValue = ExpCompValues.GetValue(Value).StringValue;
|
||||
IntValue = ExpCompValues.GetValue(Value).IntValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal CameraValue(string SValue, int IValue, double DValue)
|
||||
{
|
||||
ValueType = PropertyID.Unknown;
|
||||
StringValue = SValue;
|
||||
IntValue = IValue;
|
||||
DoubleValue = DValue;
|
||||
}
|
||||
|
||||
internal CameraValue(string SValue, int IValue, double DValue, PropertyID ValueType)
|
||||
{
|
||||
this.ValueType = ValueType;
|
||||
StringValue = SValue;
|
||||
IntValue = IValue;
|
||||
DoubleValue = DValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="CameraValue"/>s are equal to each other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||
/// <returns>True if the <see cref="CameraValue"/>s are equal; otherwise, false</returns>
|
||||
public static bool operator ==(CameraValue x, CameraValue y)
|
||||
{
|
||||
// If both are null, or both are same instance, return true.
|
||||
if (object.ReferenceEquals(x, y)) return true;
|
||||
|
||||
// If one is null, but not both, return false.
|
||||
if ((object)x == null || (object)y == null) return false;
|
||||
|
||||
return x.IntValue == y.IntValue && x.ValueType == y.ValueType;
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="CameraValue"/>s are unequal to each other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||
/// <returns>True if the <see cref="CameraValue"/>s are unequal; otherwise, false</returns>
|
||||
public static bool operator !=(CameraValue x, CameraValue y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraValue"/></param>
|
||||
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>; otherwise, false.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// If objects have different types, return false.
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
|
||||
// If both are null, or both are same instance, return true.
|
||||
if (object.ReferenceEquals(this, obj)) return true;
|
||||
|
||||
CameraValue cv = obj as CameraValue;
|
||||
if (cv == null) return false;
|
||||
|
||||
return IntValue == cv.IntValue && ValueType == cv.ValueType;
|
||||
}
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a <see cref="CameraValue"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = (int)2166136261;
|
||||
hash *= 16777619 ^ IntValue.GetHashCode();
|
||||
hash *= 16777619 ^ ValueType.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts the camera value to an int
|
||||
/// </summary>
|
||||
/// <param name="x">The camera value to convert</param>
|
||||
/// <returns>The int representing the camera value</returns>
|
||||
public static implicit operator int(CameraValue x)
|
||||
{
|
||||
return x.IntValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts the camera value to a string
|
||||
/// </summary>
|
||||
/// <param name="x">The camera value to convert</param>
|
||||
/// <returns>The string representing the camera value</returns>
|
||||
public static implicit operator string(CameraValue x)
|
||||
{
|
||||
return x.StringValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts the camera value to a double
|
||||
/// </summary>
|
||||
/// <param name="x">The camera value to convert</param>
|
||||
/// <returns>The double representing the camera value</returns>
|
||||
public static implicit operator double(CameraValue x)
|
||||
{
|
||||
return x.DoubleValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current <see cref="CameraValue"/>.
|
||||
/// </summary>
|
||||
/// <returns>A string that represents the current <see cref="CameraValue"/>.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return StringValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/CamBooth/EDSDKLib/API/Helper/Delegates.cs
Normal file
69
src/CamBooth/EDSDKLib/API/Helper/Delegates.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using EOSDigital.SDK;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// A delegate for progress
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="progress">The progress. A value between 0 and 100</param>
|
||||
public delegate void ProgressHandler(object sender, int progress);
|
||||
/// <summary>
|
||||
/// A delegate to pass a stream
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="img">An image embedded in a stream</param>
|
||||
public delegate void LiveViewUpdate(Camera sender, Stream img);
|
||||
/// <summary>
|
||||
/// A delegate to report an available download
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="Info">The data for the download</param>
|
||||
public delegate void DownloadHandler(Camera sender, DownloadInfo Info);
|
||||
/// <summary>
|
||||
/// A delegate for property changes
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="eventID">The property event ID</param>
|
||||
/// <param name="propID">The property ID</param>
|
||||
/// <param name="parameter">A parameter for additional information</param>
|
||||
public delegate void PropertyChangeHandler(Camera sender, PropertyEventID eventID, PropertyID propID, int parameter);
|
||||
/// <summary>
|
||||
/// A delegate for camera state changes
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="eventID">The state event ID</param>
|
||||
/// <param name="parameter">A parameter for additional information</param>
|
||||
public delegate void StateChangeHandler(Camera sender, StateEventID eventID, int parameter);
|
||||
/// <summary>
|
||||
/// A delegate for property changes
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="eventID">The object event ID</param>
|
||||
/// <param name="reference">A pointer to the object that has changed</param>
|
||||
public delegate void ObjectChangeHandler(Camera sender, ObjectEventID eventID, IntPtr reference);
|
||||
/// <summary>
|
||||
/// A delegate to inform of an added camera
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
public delegate void CameraAddedHandler(CanonAPI sender);
|
||||
/// <summary>
|
||||
/// A delegate to inform of a change of a camera
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
public delegate void CameraUpdateHandler(Camera sender);
|
||||
/// <summary>
|
||||
/// A delegate to inform of SDK exceptions
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="ex">The SDK exception</param>
|
||||
public delegate void SDKExceptionHandler(object sender, ErrorCode ex);
|
||||
/// <summary>
|
||||
/// A delegate to inform of exceptions
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="ex">The exception</param>
|
||||
public delegate void GeneralExceptionHandler(object sender, Exception ex);
|
||||
}
|
||||
421
src/CamBooth/EDSDKLib/API/Helper/ExceptionHandling.cs
Normal file
421
src/CamBooth/EDSDKLib/API/Helper/ExceptionHandling.cs
Normal file
@ -0,0 +1,421 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using EOSDigital.SDK;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// An Exception that happened while handling the Canon SDK
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class SDKException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// The specific SDK error code that happened
|
||||
/// </summary>
|
||||
public ErrorCode Error { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class
|
||||
/// </summary>
|
||||
public SDKException()
|
||||
{
|
||||
Error = ErrorCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error code
|
||||
/// </summary>
|
||||
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||
public SDKException(ErrorCode Error)
|
||||
: base(Error.ToString())
|
||||
{
|
||||
this.Error = Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
public SDKException(string message)
|
||||
: base(message)
|
||||
{
|
||||
Error = ErrorCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
|
||||
/// error message and a reference to the inner exception that is the cause of
|
||||
/// this exception
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||
public SDKException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
Error = ErrorCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message and error code
|
||||
/// </summary>
|
||||
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
public SDKException(string message, ErrorCode Error)
|
||||
: base(message)
|
||||
{
|
||||
this.Error = Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
|
||||
/// error message, error code and a reference to the inner exception that is the cause of
|
||||
/// this exception
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||
/// (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
public SDKException(string message, ErrorCode Error, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
this.Error = Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKException"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||
/// object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||
/// information about the source or destination.</param>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
private SDKException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
Error = (ErrorCode)info.GetUInt32("Error");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||
/// with information about the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||
/// that holds the serialized object data about the exception being thrown</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/>
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
info.AddValue("Error", Error);
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Exception that states a problem with the session state of the camera
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class CameraSessionException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CameraSessionException"/> class
|
||||
/// </summary>
|
||||
public CameraSessionException()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified error message
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
public CameraSessionException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified
|
||||
/// error message and a reference to the inner exception that is the cause of
|
||||
/// this exception
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||
public CameraSessionException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||
/// object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||
/// information about the source or destination.</param>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
private CameraSessionException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||
/// with information about the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||
/// that holds the serialized object data about the exception being thrown</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/>
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Exception that states a problem with the state of the Canon SDK
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class SDKStateException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKStateException"/> class
|
||||
/// </summary>
|
||||
public SDKStateException()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified error message
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
public SDKStateException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified
|
||||
/// error message and a reference to the inner exception that is the cause of
|
||||
/// this exception
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||
public SDKStateException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SDKStateException"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||
/// object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||
/// information about the source or destination.</param>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
private SDKStateException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||
/// with information about the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||
/// that holds the serialized object data about the exception being thrown</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/>
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An Exception that happened while executing on an STA thread
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class ExecutionException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a specified error message
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
public ExecutionException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a reference to
|
||||
/// the inner exception that is the cause of this exception
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||
public ExecutionException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExecutionException"/> class with serialized data.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||
/// object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||
/// information about the source or destination.</param>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
private ExecutionException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||
/// with information about the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||
/// that holds the serialized object data about the exception being thrown</param>
|
||||
/// <param name="context">The <see cref="StreamingContext"/>
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles errors and provides events for errors (e.g. focus problems or general exceptions)
|
||||
/// </summary>
|
||||
public static class ErrorHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// If an error happened, that does not break the program, this event is fired (e.g. a focus error)
|
||||
/// </summary>
|
||||
public static event SDKExceptionHandler NonSevereErrorHappened;
|
||||
/// <summary>
|
||||
/// If an error happened on a thread that does not fall into the non-severe category, this event is fired
|
||||
/// </summary>
|
||||
public static event GeneralExceptionHandler SevereErrorHappened;
|
||||
/// <summary>
|
||||
/// List of all non-severe errors. Items can be added or removed.
|
||||
/// </summary>
|
||||
public static List<ErrorCode> NonSevereErrors { get; private set; }
|
||||
|
||||
static ErrorHandler()
|
||||
{
|
||||
NonSevereErrors = new List<ErrorCode>()
|
||||
{
|
||||
ErrorCode.TAKE_PICTURE_AF_NG,
|
||||
ErrorCode.TAKE_PICTURE_CARD_NG,
|
||||
ErrorCode.TAKE_PICTURE_CARD_PROTECT_NG,
|
||||
ErrorCode.TAKE_PICTURE_LV_REL_PROHIBIT_MODE_NG,
|
||||
ErrorCode.TAKE_PICTURE_MIRROR_UP_NG,
|
||||
ErrorCode.TAKE_PICTURE_MOVIE_CROP_NG,
|
||||
ErrorCode.TAKE_PICTURE_NO_CARD_NG,
|
||||
ErrorCode.TAKE_PICTURE_NO_LENS_NG,
|
||||
ErrorCode.TAKE_PICTURE_SENSOR_CLEANING_NG,
|
||||
ErrorCode.TAKE_PICTURE_SILENCE_NG,
|
||||
ErrorCode.TAKE_PICTURE_SPECIAL_MOVIE_MODE_NG,
|
||||
ErrorCode.TAKE_PICTURE_STROBO_CHARGE_NG,
|
||||
ErrorCode.LENS_COVER_CLOSE,
|
||||
ErrorCode.DEVICE_BUSY,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for an error in SDK calls and checks how to treat it
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender object</param>
|
||||
/// <param name="errorCode">The return code of the SDK call</param>
|
||||
/// <exception cref="SDKException">If a severe error is recognized or the <see cref="NonSevereErrorHappened"/>
|
||||
/// event is null with a non-severe error, it will be thrown as an exception</exception>
|
||||
public static void CheckError(object sender, ErrorCode errorCode)
|
||||
{
|
||||
if (errorCode == ErrorCode.OK) return;
|
||||
else
|
||||
{
|
||||
bool Severe = !NonSevereErrors.Any(t => t == errorCode);
|
||||
|
||||
var NonSevereErrorHappenedEvent = NonSevereErrorHappened;
|
||||
if (!Severe) Severe = NonSevereErrorHappenedEvent == null;
|
||||
|
||||
if (Severe) throw new SDKException(errorCode);
|
||||
else NonSevereErrorHappenedEvent.BeginInvoke(sender, errorCode, (a) =>
|
||||
{
|
||||
var ar = a as AsyncResult;
|
||||
var invokedMethod = ar.AsyncDelegate as SDKExceptionHandler;
|
||||
invokedMethod.EndInvoke(a);
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for an error in SDK calls and throws an exception if it's not <see cref="ErrorCode.OK"/>
|
||||
/// </summary>
|
||||
/// <param name="errorCode">The return code of the SDK call</param>
|
||||
/// <exception cref="SDKException">If <paramref name="errorCode"/> is something other than <see cref="ErrorCode.OK"/></exception>
|
||||
public static void CheckError(ErrorCode errorCode)
|
||||
{
|
||||
if (errorCode != ErrorCode.OK) throw new SDKException(errorCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
|
||||
/// and throws an exception if it's not valid
|
||||
/// </summary>
|
||||
/// <param name="countOrError">The return code of the SDK call</param>
|
||||
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
|
||||
public static int CheckError(int countOrError)
|
||||
{
|
||||
if (countOrError == unchecked((int)0xFFFFFFFF)) throw new SDKException(ErrorCode.INVALID_HANDLE);
|
||||
else return countOrError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
|
||||
/// and throws an exception if it's not valid
|
||||
/// </summary>
|
||||
/// <param name="sender">The calling object instance. This is currently not used and is ignored.</param>
|
||||
/// <param name="countOrError">The return code of the SDK call</param>
|
||||
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
|
||||
public static int CheckError(object sender, int countOrError)
|
||||
{
|
||||
return CheckError(countOrError);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports an error that happened in a threading environment
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender object</param>
|
||||
/// <param name="ex">The exception that happened</param>
|
||||
/// <returns>True if the error could be passed on; false otherwise</returns>
|
||||
public static bool ReportError(object sender, Exception ex)
|
||||
{
|
||||
var SevereErrorHappenedEvent = SevereErrorHappened;
|
||||
if (SevereErrorHappenedEvent == null) return false;
|
||||
else
|
||||
{
|
||||
SevereErrorHappenedEvent.BeginInvoke(sender, ex, (a) =>
|
||||
{
|
||||
var ar = a as AsyncResult;
|
||||
var invokedMethod = ar.AsyncDelegate as GeneralExceptionHandler;
|
||||
invokedMethod.EndInvoke(a);
|
||||
}, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
554
src/CamBooth/EDSDKLib/API/Helper/IO.cs
Normal file
554
src/CamBooth/EDSDKLib/API/Helper/IO.cs
Normal file
@ -0,0 +1,554 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using EOSDigital.SDK;
|
||||
using SeekOrigin = System.IO.SeekOrigin;
|
||||
using FileAccess = EOSDigital.SDK.FileAccess;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores information to download data from the camera
|
||||
/// </summary>
|
||||
public class DownloadInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Pointer to the downloadable object
|
||||
/// </summary>
|
||||
protected IntPtr inRef;
|
||||
/// <summary>
|
||||
/// Directory item info of the downloadable object
|
||||
/// </summary>
|
||||
protected DirectoryItemInfo dirInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Pointer to the downloadable object
|
||||
/// </summary>
|
||||
public IntPtr Reference { get { return inRef; } }
|
||||
/// <summary>
|
||||
/// The name of the file. You can change it before you pass it to the
|
||||
/// <see cref="Camera.DownloadFile(DownloadInfo)"/> or
|
||||
/// <see cref="Camera.DownloadFile(DownloadInfo, string)"/> method.
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get { return dirInfo.FileName; }
|
||||
set { dirInfo.FileName = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// The files size in bytes
|
||||
/// </summary>
|
||||
public int Size { get { return dirInfo.Size; } }
|
||||
/// <summary>
|
||||
/// The files size in bytes (as ulong)
|
||||
/// </summary>
|
||||
public long Size64 { get { return dirInfo.Size64; } }
|
||||
/// <summary>
|
||||
/// States if the file is a RAW file or not
|
||||
/// </summary>
|
||||
public bool IsRAW { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DownloadInfo"/> class
|
||||
/// </summary>
|
||||
/// <param name="inRef">Pointer to the downloadable object</param>
|
||||
internal protected DownloadInfo(IntPtr inRef)
|
||||
{
|
||||
if (inRef == IntPtr.Zero) throw new ArgumentNullException(nameof(inRef));
|
||||
|
||||
this.inRef = inRef;
|
||||
ErrorHandler.CheckError(this, CanonSDK.GetDirectoryItemInfo(inRef, out dirInfo));
|
||||
string ext = Path.GetExtension(FileName).ToLower();
|
||||
if (ext == ".crw" || ext == ".cr2") IsRAW = true;
|
||||
else IsRAW = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores information about a file or folder in a camera
|
||||
/// </summary>
|
||||
public partial class CameraFileEntry : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Pointer to the file entry
|
||||
/// </summary>
|
||||
public IntPtr Reference { get { return Ref; } }
|
||||
/// <summary>
|
||||
/// The name of the entry. (volume name, folder name or file name)
|
||||
/// </summary>
|
||||
public string Name { get; protected set; }
|
||||
/// <summary>
|
||||
/// States if the entry is a folder or not
|
||||
/// </summary>
|
||||
public bool IsFolder { get; protected set; }
|
||||
/// <summary>
|
||||
/// States if the entry is a volume or not
|
||||
/// </summary>
|
||||
public bool IsVolume { get; protected set; }
|
||||
/// <summary>
|
||||
/// If the entry is a volume or folder, these are the subentries it contains. It's null if no subentries are present.
|
||||
/// </summary>
|
||||
public CameraFileEntry[] Entries { get; internal protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pointer to the file entry
|
||||
/// </summary>
|
||||
protected IntPtr Ref;
|
||||
/// <summary>
|
||||
/// States if the entry is disposed or not
|
||||
/// </summary>
|
||||
internal protected bool IsDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="CameraFileEntry"/> class
|
||||
/// </summary>
|
||||
/// <param name="Ref"></param>
|
||||
/// <param name="Name"></param>
|
||||
/// <param name="IsFolder"></param>
|
||||
/// <param name="IsVolume"></param>
|
||||
internal protected CameraFileEntry(IntPtr Ref, string Name, bool IsFolder, bool IsVolume)
|
||||
{
|
||||
this.Ref = Ref;
|
||||
this.Name = Name;
|
||||
this.IsFolder = IsFolder;
|
||||
this.IsVolume = IsVolume;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
~CameraFileEntry()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases this entry but not the subentries
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases this entry and all the subentries
|
||||
/// </summary>
|
||||
public void DisposeAll()
|
||||
{
|
||||
Dispose();
|
||||
if (Entries != null) for (int i = 0; i < Entries.Length; i++) Entries[i].DisposeAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases this entry but not the subentries
|
||||
/// </summary>
|
||||
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
|
||||
protected virtual void Dispose(bool managed)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
if (managed) DisposeThumb();
|
||||
if (Reference != IntPtr.Zero) CanonSDK.EdsRelease(Reference);
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the thumbnail in an extension
|
||||
/// </summary>
|
||||
partial void DisposeThumb();
|
||||
|
||||
/// <summary>
|
||||
/// Set the thumbnail from a stream. The thumbnail depends on the image class you want to use.
|
||||
/// </summary>
|
||||
/// <param name="stream">The image stream</param>
|
||||
internal protected virtual void SetThumb(IntPtr stream)
|
||||
{
|
||||
SetThumbSub(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the thumbnail
|
||||
/// </summary>
|
||||
/// <param name="stream">The image stream</param>
|
||||
partial void SetThumbSub(IntPtr stream);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="CameraFileEntry"/>s are equal to each other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
|
||||
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
|
||||
/// <returns>True if the <see cref="CameraFileEntry"/>s are equal; otherwise, false</returns>
|
||||
public static bool operator ==(CameraFileEntry x, CameraFileEntry y)
|
||||
{
|
||||
// If both are null, or both are same instance, return true.
|
||||
if (object.ReferenceEquals(x, y)) return true;
|
||||
|
||||
// If one is null, but not both, return false.
|
||||
if ((object)x == null || (object)y == null) return false;
|
||||
|
||||
return x.Reference == y.Reference;
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="CameraFileEntry"/>s are unequal to each other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
|
||||
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
|
||||
/// <returns>True if the <see cref="CameraFileEntry"/>s are unequal; otherwise, false</returns>
|
||||
public static bool operator !=(CameraFileEntry x, CameraFileEntry y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraFileEntry"/></param>
|
||||
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>; otherwise, false.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
// If objects have different types, return false.
|
||||
if (obj.GetType() != GetType()) return false;
|
||||
|
||||
// If both are null, or both are same instance, return true.
|
||||
if (object.ReferenceEquals(this, obj)) return true;
|
||||
|
||||
CameraFileEntry cv = obj as CameraFileEntry;
|
||||
if (cv == null) return false;
|
||||
|
||||
return Reference == cv.Reference;
|
||||
}
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a <see cref="CameraFileEntry"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the current <see cref="CameraFileEntry"/></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Reference.ToInt64().GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Stream encapsulating an unmanaged SDK Stream.
|
||||
/// This class can be used to overcome the differences between SDK versions
|
||||
/// </summary>
|
||||
public class SDKStream : Stream
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports reading.
|
||||
/// </summary>
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports seeking.
|
||||
/// </summary>
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current stream supports writing.
|
||||
/// </summary>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the length in bytes of the stream.
|
||||
/// </summary>
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CanonSDK.IsVerGE34)
|
||||
{
|
||||
long length;
|
||||
CanonSDK.EdsGetLength(Reference, out length);
|
||||
return length;
|
||||
}
|
||||
else
|
||||
{
|
||||
int length;
|
||||
CanonSDK.EdsGetLength(Reference, out length);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the position within the current stream.
|
||||
/// </summary>
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CanonSDK.IsVerGE34)
|
||||
{
|
||||
long position;
|
||||
CanonSDK.EdsGetPosition(Reference, out position);
|
||||
return position;
|
||||
}
|
||||
else
|
||||
{
|
||||
int position;
|
||||
CanonSDK.EdsGetPosition(Reference, out position);
|
||||
return position;
|
||||
}
|
||||
}
|
||||
set { Seek(value, SeekOrigin.Begin); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Pointer to the underlying SDK stream
|
||||
/// </summary>
|
||||
public IntPtr Reference
|
||||
{
|
||||
get { return _Reference; }
|
||||
protected set { _Reference = value; }
|
||||
}
|
||||
private IntPtr _Reference;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream
|
||||
/// </summary>
|
||||
/// <param name="sdkStream">Pointer to the SDK stream</param>
|
||||
public SDKStream(IntPtr sdkStream)
|
||||
{
|
||||
if (sdkStream == IntPtr.Zero) throw new ArgumentNullException(nameof(sdkStream));
|
||||
Reference = sdkStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK file stream
|
||||
/// </summary>
|
||||
/// <param name="filepath">Path to the file</param>
|
||||
/// <param name="createDisposition">State how to create the stream</param>
|
||||
/// <param name="access">File access type</param>
|
||||
public SDKStream(string filepath, FileCreateDisposition createDisposition, FileAccess access)
|
||||
{
|
||||
if (filepath == null) throw new ArgumentNullException(nameof(filepath));
|
||||
ErrorHandler.CheckError(CanonSDK.EdsCreateFileStreamEx(filepath, createDisposition, access, out _Reference));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||
/// This stream will resize itself if the current length is exceeded
|
||||
/// </summary>
|
||||
/// <param name="length">Initial buffer size of the stream in bytes</param>
|
||||
public SDKStream(long length)
|
||||
{
|
||||
ErrorCode err;
|
||||
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStream(length, out _Reference);
|
||||
else err = CanonSDK.EdsCreateMemoryStream((int)length, out _Reference);
|
||||
ErrorHandler.CheckError(err);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||
/// Note that this stream will not resize itself
|
||||
/// </summary>
|
||||
/// <param name="buffer">The memory buffer to use for the stream</param>
|
||||
public SDKStream(byte[] buffer)
|
||||
{
|
||||
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
|
||||
|
||||
ErrorCode err;
|
||||
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, buffer.LongLength, out _Reference);
|
||||
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)buffer.LongLength, out _Reference);
|
||||
ErrorHandler.CheckError(err);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||
/// Note that this stream will not resize itself
|
||||
/// </summary>
|
||||
/// <param name="buffer">Pointer to the memory buffer to use for the stream</param>
|
||||
/// <param name="length">The size of the memory buffer in bytes</param>
|
||||
public SDKStream(IntPtr buffer, long length)
|
||||
{
|
||||
if (buffer == IntPtr.Zero) throw new ArgumentNullException(nameof(buffer));
|
||||
|
||||
ErrorCode err;
|
||||
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, length, out _Reference);
|
||||
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)length, out _Reference);
|
||||
ErrorHandler.CheckError(err);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream.
|
||||
/// Note that this calls <see cref="SDKStream(IntPtr)"/> internally and ignores all parameters but <paramref name="sdkStream"/>
|
||||
/// </summary>
|
||||
/// <param name="buffer">Pointer to the underlying SDK buffer. Ignored parameter</param>
|
||||
/// <param name="sdkStream">Pointer to the SDK stream</param>
|
||||
/// <param name="length">The size of the underlying SDK buffer in bytes. Ignored parameter</param>
|
||||
[Obsolete("Not necessary anymore. Buffer and length is not used.")]
|
||||
public SDKStream(IntPtr buffer, IntPtr sdkStream, long length)
|
||||
: this(sdkStream)
|
||||
{ }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all buffers for this stream and causes any buffered data to be
|
||||
/// written to the underlying device.
|
||||
/// This is not applicable to the SDK and therefore does nothing.
|
||||
/// </summary>
|
||||
public override void Flush()
|
||||
{
|
||||
//Nothing to do here
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current stream and advances the position
|
||||
/// within the stream by the number of bytes read.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||
/// byte array with the values between offset and (offset + count - 1) replaced by
|
||||
/// the bytes read from the current source.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||
/// from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>The total number of bytes read into the buffer. This can be less than the number
|
||||
/// of bytes requested if that many bytes are not currently available, or zero (0)
|
||||
/// if the end of the stream has been reached.</returns>
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return (int)Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current stream and advances the position
|
||||
/// within the stream by the number of bytes read.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||
/// byte array with the values between offset and (offset + count - 1) replaced by
|
||||
/// the bytes read from the current source.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||
/// from the current stream.</param>
|
||||
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||
/// <returns>The total number of bytes read into the buffer. This can be less than the number
|
||||
/// of bytes requested if that many bytes are not currently available, or zero (0)
|
||||
/// if the end of the stream has been reached.</returns>
|
||||
public unsafe long Read(byte[] buffer, long offset, long count)
|
||||
{
|
||||
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
|
||||
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
byte* offsetBufferPtr = bufferPtr + offset;
|
||||
|
||||
if (CanonSDK.IsVerGE34)
|
||||
{
|
||||
long read;
|
||||
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, count, (IntPtr)offsetBufferPtr, out read));
|
||||
return read;
|
||||
}
|
||||
else
|
||||
{
|
||||
int read;
|
||||
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, (int)count, (IntPtr)offsetBufferPtr, out read));
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position within the current stream.
|
||||
/// </summary>
|
||||
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||
/// reference point used to obtain the new position.</param>
|
||||
/// <returns>The new position within the current stream.</returns>
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
SDK.SeekOrigin sdkOrigin;
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
sdkOrigin = SDK.SeekOrigin.Begin;
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
sdkOrigin = SDK.SeekOrigin.Current;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
sdkOrigin = SDK.SeekOrigin.End;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Not a valid enum value", nameof(origin));
|
||||
}
|
||||
|
||||
if (CanonSDK.IsVerGE34) ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, offset, sdkOrigin));
|
||||
else ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, (int)offset, sdkOrigin));
|
||||
|
||||
return Position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Always throws a <see cref="NotSupportedException"/>
|
||||
/// </summary>
|
||||
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current stream and advances
|
||||
/// the current position within this stream by the number of bytes written.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
|
||||
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
Write(buffer, (long)offset, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current stream and advances
|
||||
/// the current position within this stream by the number of bytes written.
|
||||
/// </summary>
|
||||
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
|
||||
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||
public unsafe void Write(byte[] buffer, long offset, long count)
|
||||
{
|
||||
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
|
||||
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
byte* offsetBufferPtr = bufferPtr + offset;
|
||||
|
||||
if (CanonSDK.IsVerGE34)
|
||||
{
|
||||
long written;
|
||||
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, count, (IntPtr)offsetBufferPtr, out written));
|
||||
}
|
||||
else
|
||||
{
|
||||
int written;
|
||||
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, (int)count, (IntPtr)offsetBufferPtr, out written));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the unmanaged resources used by the <see cref="SDKStream"/> and optionally
|
||||
/// releases the managed resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true to release both managed and unmanaged resources;
|
||||
/// false to release only unmanaged</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (_Reference != IntPtr.Zero)
|
||||
{
|
||||
int err = CanonSDK.EdsRelease(_Reference);
|
||||
Reference = IntPtr.Zero;
|
||||
if (disposing) ErrorHandler.CheckError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
324
src/CamBooth/EDSDKLib/API/Helper/STAThread.cs
Normal file
324
src/CamBooth/EDSDKLib/API/Helper/STAThread.cs
Normal file
@ -0,0 +1,324 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// This static class executes things on an STA thread and provides a method to create an STA thread
|
||||
/// </summary>
|
||||
public class STAThread
|
||||
{
|
||||
#region Variables
|
||||
|
||||
/// <summary>
|
||||
/// Object that is used for the lock keyword to ensure only one SDK command is executed at a time
|
||||
/// </summary>
|
||||
public static readonly object ExecLock = new object();
|
||||
/// <summary>
|
||||
/// States if the calling thread is in a Single Threaded Apartment or not
|
||||
/// </summary>
|
||||
public static bool IsSTAThread
|
||||
{
|
||||
get { return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// States if this thread is currently running
|
||||
/// </summary>
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return isRunning; }
|
||||
}
|
||||
/// <summary>
|
||||
/// ID of the associated thread
|
||||
/// </summary>
|
||||
public int ThreadID
|
||||
{
|
||||
get { return mainThread.ManagedThreadId; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main thread where everything will be executed on
|
||||
/// </summary>
|
||||
private Thread mainThread;
|
||||
/// <summary>
|
||||
/// States if the execution thread is currently running
|
||||
/// </summary>
|
||||
private bool isRunning = false;
|
||||
|
||||
/// <summary>
|
||||
/// Lock object to make sure only one command at a time is executed
|
||||
/// </summary>
|
||||
private object runLock = new object();
|
||||
/// <summary>
|
||||
/// Lock object to ensure that an action executed on the thread does not invoke on itself
|
||||
/// </summary>
|
||||
private object cmdLock = new object();
|
||||
/// <summary>
|
||||
/// Lock object to synchronize between execution and calling thread
|
||||
/// </summary>
|
||||
protected object threadLock1 = new object();
|
||||
/// <summary>
|
||||
/// Lock object to synchronize between execution and calling thread
|
||||
/// </summary>
|
||||
private object threadLock2 = new object();
|
||||
/// <summary>
|
||||
/// States if the first lock is currently blocking or not
|
||||
/// </summary>
|
||||
protected bool block1 = true;
|
||||
/// <summary>
|
||||
/// States if the second lock is currently blocking or not
|
||||
/// </summary>
|
||||
private bool block2 = true;
|
||||
|
||||
/// <summary>
|
||||
/// The action to be executed
|
||||
/// </summary>
|
||||
private Action runAction;
|
||||
/// <summary>
|
||||
/// Storage for an exception that might have happened on the execution thread
|
||||
/// </summary>
|
||||
private Exception runException;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="STAThread"/> class
|
||||
/// </summary>
|
||||
internal STAThread()
|
||||
{ }
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Starts the execution loop
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
lock (runLock)
|
||||
{
|
||||
if (!isRunning)
|
||||
{
|
||||
mainThread = CreateThread(ExecutionLoop);
|
||||
isRunning = true;
|
||||
mainThread.Start();
|
||||
WaitForThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down the execution loop and waits for it to finish
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (runLock)
|
||||
{
|
||||
if (isRunning)
|
||||
{
|
||||
isRunning = false;
|
||||
NotifyThread();
|
||||
mainThread.Join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes an action on this STA thread
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute</param>
|
||||
/// <exception cref="ArgumentNullException">will be thrown if action is null</exception>
|
||||
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
|
||||
/// it will be rethrown as inner exception of this exception</exception>
|
||||
public void Invoke(Action action)
|
||||
{
|
||||
if (action == null) throw new ArgumentNullException(nameof(action));
|
||||
|
||||
//If the method is called from the execution thread, directly execute it.
|
||||
//This prevents possible deadlocks when trying to acquire the runLock while waiting within for the thread to finish.
|
||||
if (Monitor.TryEnter(cmdLock))
|
||||
{
|
||||
try { action(); }
|
||||
finally { Monitor.Exit(cmdLock); }
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (runLock)
|
||||
{
|
||||
if (!isRunning) throw new InvalidOperationException("Thread is not running");
|
||||
|
||||
runAction = action;
|
||||
NotifyThread();
|
||||
WaitForThread();
|
||||
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function on this STA thread
|
||||
/// </summary>
|
||||
/// <param name="func">The function to execute</param>
|
||||
/// <returns>the return value of the function</returns>
|
||||
/// <exception cref="ArgumentNullException">will be thrown if func is null</exception>
|
||||
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
|
||||
/// it will be rethrown as inner exception of this exception</exception>
|
||||
public T Invoke<T>(Func<T> func)
|
||||
{
|
||||
if (func == null) throw new ArgumentNullException(nameof(func));
|
||||
|
||||
T result = default(T);
|
||||
Invoke(delegate { result = func(); });
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a thread in a Single Threaded Apartment
|
||||
/// </summary>
|
||||
/// <param name="action">The command to run on this thread</param>
|
||||
/// <returns>An STA thread</returns>
|
||||
public static Thread CreateThread(Action action)
|
||||
{
|
||||
var thread = new Thread(new ThreadStart(action));
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
return thread;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes an action on a newly created STA Thread
|
||||
/// and optionally waits for it to finish executing
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute</param>
|
||||
/// <param name="wait">If true, the action is executed synchronously or if false, asynchronously.</param>
|
||||
public static void ExecuteThread(Action action, bool wait)
|
||||
{
|
||||
Exception runException = null;
|
||||
Thread thread = CreateThread(delegate
|
||||
{
|
||||
try { action(); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (wait) runException = ex;
|
||||
else throw;
|
||||
}
|
||||
});
|
||||
|
||||
thread.Start();
|
||||
|
||||
if (wait)
|
||||
{
|
||||
thread.Join();
|
||||
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function on a newly created STA Thread
|
||||
/// </summary>
|
||||
/// <param name="func">The function to execute</param>
|
||||
/// <returns>The return value of the given function</returns>
|
||||
public static T ExecuteThread<T>(Func<T> func)
|
||||
{
|
||||
Exception runException = null;
|
||||
T result = default(T);
|
||||
Thread thread = CreateThread(delegate
|
||||
{
|
||||
try { result = func(); }
|
||||
catch (Exception ex) { runException = ex; }
|
||||
});
|
||||
thread.Start();
|
||||
thread.Join();
|
||||
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Subroutines
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the execution loop to execute something
|
||||
/// </summary>
|
||||
private void NotifyThread()
|
||||
{
|
||||
lock (threadLock1)
|
||||
{
|
||||
block1 = false;
|
||||
Monitor.Pulse(threadLock1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blocks until the execution loop is done with the work
|
||||
/// </summary>
|
||||
private void WaitForThread()
|
||||
{
|
||||
lock (threadLock2)
|
||||
{
|
||||
while (block2) Monitor.Wait(threadLock2);
|
||||
block2 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the waiting <see cref="WaitForThread"/> method to continue
|
||||
/// </summary>
|
||||
private void ReleaseWait()
|
||||
{
|
||||
lock (threadLock2)
|
||||
{
|
||||
block2 = false;
|
||||
Monitor.Pulse(threadLock2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The waiting routine on the execution loop
|
||||
/// </summary>
|
||||
protected virtual void WaitForNotification()
|
||||
{
|
||||
lock (threadLock1)
|
||||
{
|
||||
while (block1 && isRunning) { Monitor.Wait(threadLock1); }
|
||||
block1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The loop that is executed on the thread and where the work is done
|
||||
/// </summary>
|
||||
private void ExecutionLoop()
|
||||
{
|
||||
ReleaseWait();
|
||||
|
||||
try
|
||||
{
|
||||
lock (cmdLock)
|
||||
{
|
||||
while (isRunning)
|
||||
{
|
||||
WaitForNotification();
|
||||
if (!isRunning) return;
|
||||
|
||||
runException = null;
|
||||
try { lock (ExecLock) { runAction(); } }
|
||||
catch (Exception ex) { runException = ex; }
|
||||
|
||||
ReleaseWait();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
isRunning = false;
|
||||
ReleaseWait();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
788
src/CamBooth/EDSDKLib/API/Helper/ValueCollections.cs
Normal file
788
src/CamBooth/EDSDKLib/API/Helper/ValueCollections.cs
Normal file
@ -0,0 +1,788 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using EOSDigital.SDK;
|
||||
|
||||
namespace EOSDigital.API
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores CameraValues and provides methods to get those values. Abstract class.
|
||||
/// </summary>
|
||||
public abstract class ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the value from an int out of given possible values.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||
/// <returns>The CameraValue with given uint representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value, List<CameraValue> Values)
|
||||
{
|
||||
var arr = Values.Where(t => t.IntValue == value).ToArray();
|
||||
if (arr.Length == 0)
|
||||
{
|
||||
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
|
||||
if (invalid != null) return invalid;
|
||||
else throw new KeyNotFoundException("There is no CameraValue for this ID");
|
||||
}
|
||||
else { return arr[0]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string out of given possible values.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value, List<CameraValue> Values)
|
||||
{
|
||||
var arr = Values.Where(t => t.StringValue == value).ToArray();
|
||||
if (arr.Length == 0)
|
||||
{
|
||||
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
|
||||
if (invalid != null) return invalid;
|
||||
else throw new KeyNotFoundException("There is no CameraValue for this ID");
|
||||
}
|
||||
else { return arr[0]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double out of given possible values.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value, List<CameraValue> Values)
|
||||
{
|
||||
CameraValue[] sorted = Values.Distinct(new CameraValueComparer())
|
||||
.Where(t => t.IntValue != unchecked((int)0xFFFFFFFF) && t != TvValues.Bulb && t != ISOValues.Auto)
|
||||
.OrderBy(t => t.DoubleValue).ToArray();
|
||||
|
||||
for (int i = 0; i < sorted.Length; i++)
|
||||
{
|
||||
//Exact match:
|
||||
if (Math.Abs(sorted[i].DoubleValue - value) <= 0.00000000001) return sorted[i];
|
||||
else if (sorted[i].DoubleValue > value)
|
||||
{
|
||||
//Value is smaller than the range of given list. Return first:
|
||||
if (i == 0) return sorted[i];
|
||||
else
|
||||
{
|
||||
//Select CameraValue closest to given value
|
||||
double delta1 = value - sorted[i - 1].DoubleValue;
|
||||
double delta = sorted[i].DoubleValue - value;
|
||||
if (delta > delta1) return sorted[i - 1];
|
||||
else return sorted[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Value is bigger than the range of given list. Return last:
|
||||
return sorted[sorted.Length - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparer for <see cref="CameraValue"/>s
|
||||
/// </summary>
|
||||
protected sealed class CameraValueComparer : IEqualityComparer<CameraValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="CameraValue"/>s are equal.
|
||||
/// </summary>
|
||||
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||
/// <returns>true if the specified <see cref="CameraValue"/>s are equal; otherwise, false.</returns>
|
||||
public bool Equals(CameraValue x, CameraValue y)
|
||||
{
|
||||
return x.Equals(y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a <see cref="CameraValue"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
|
||||
public int GetHashCode(CameraValue obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores Av Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class AvValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
/// <summary>
|
||||
/// The Av <see cref="CameraValue"/> of the "Auto" or "None" setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Av);
|
||||
/// <summary>
|
||||
/// The Av <see cref="CameraValue"/> of an invalid setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Av);
|
||||
|
||||
static AvValues()
|
||||
{
|
||||
values = new List<CameraValue>()
|
||||
{
|
||||
Auto,
|
||||
new CameraValue("1", 0x08, 1, PropertyID.Av),
|
||||
new CameraValue("1.1", 0x0B, 1.1, PropertyID.Av),
|
||||
new CameraValue("1.2", 0x0C, 1.2, PropertyID.Av),
|
||||
new CameraValue("1.2 (1/3)", 0x0D, 1.2, PropertyID.Av),
|
||||
new CameraValue("1.4", 0x10, 1.4, PropertyID.Av),
|
||||
new CameraValue("1.6", 0x13, 1.6, PropertyID.Av),
|
||||
new CameraValue("1.8", 0x14, 1.8, PropertyID.Av),
|
||||
new CameraValue("1.8 (1/3)", 0x15, 1.8, PropertyID.Av),
|
||||
new CameraValue("2", 0x18, 2, PropertyID.Av),
|
||||
new CameraValue("2.2", 0x1B, 2.2, PropertyID.Av),
|
||||
new CameraValue("2.5", 0x1C, 2.5, PropertyID.Av),
|
||||
new CameraValue("2.5 (1/3)", 0x1D, 2.5, PropertyID.Av),
|
||||
new CameraValue("2.8", 0x20, 2.8, PropertyID.Av),
|
||||
new CameraValue("3.2", 0x23, 3.2, PropertyID.Av),
|
||||
new CameraValue("3.5", 0x24, 3.5, PropertyID.Av),
|
||||
new CameraValue("3.5 (1/3)", 0x25, 3.5, PropertyID.Av),
|
||||
new CameraValue("4", 0x28, 4, PropertyID.Av),
|
||||
new CameraValue("4.5", 0x2B, 4.5, PropertyID.Av),
|
||||
new CameraValue("4.5 (1/3)", 0x2C, 4.5, PropertyID.Av),
|
||||
new CameraValue("5.0", 0x2D, 5.0, PropertyID.Av),
|
||||
new CameraValue("5.6", 0x30, 5.6, PropertyID.Av),
|
||||
new CameraValue("6.3", 0x33, 6.3, PropertyID.Av),
|
||||
new CameraValue("6.7", 0x34, 6.7, PropertyID.Av),
|
||||
new CameraValue("7.1", 0x35, 7.1, PropertyID.Av),
|
||||
new CameraValue("8", 0x38, 8, PropertyID.Av),
|
||||
new CameraValue("9", 0x3B, 9, PropertyID.Av),
|
||||
new CameraValue("9.5", 0x3C, 9.5, PropertyID.Av),
|
||||
new CameraValue("10", 0x3D, 10, PropertyID.Av),
|
||||
new CameraValue("11", 0x40, 11, PropertyID.Av),
|
||||
new CameraValue("13 (1/3)", 0x43, 13, PropertyID.Av),
|
||||
new CameraValue("13", 0x44, 13, PropertyID.Av),
|
||||
new CameraValue("14", 0x45, 14, PropertyID.Av),
|
||||
new CameraValue("16", 0x48, 16, PropertyID.Av),
|
||||
new CameraValue("18", 0x4B, 18, PropertyID.Av),
|
||||
new CameraValue("19", 0x4C, 19, PropertyID.Av),
|
||||
new CameraValue("20", 0x4D, 20, PropertyID.Av),
|
||||
new CameraValue("22", 0x50, 22, PropertyID.Av),
|
||||
new CameraValue("25", 0x53, 25, PropertyID.Av),
|
||||
new CameraValue("27", 0x54, 27, PropertyID.Av),
|
||||
new CameraValue("29", 0x55, 29, PropertyID.Av),
|
||||
new CameraValue("32", 0x58, 32, PropertyID.Av),
|
||||
new CameraValue("36", 0x5B, 36, PropertyID.Av),
|
||||
new CameraValue("38", 0x5C, 38, PropertyID.Av),
|
||||
new CameraValue("40", 0x5D, 40, PropertyID.Av),
|
||||
new CameraValue("45", 0x60, 45, PropertyID.Av),
|
||||
new CameraValue("51", 0x63, 51, PropertyID.Av),
|
||||
new CameraValue("54", 0x64, 54, PropertyID.Av),
|
||||
new CameraValue("57", 0x65, 57, PropertyID.Av),
|
||||
new CameraValue("64", 0x68, 64, PropertyID.Av),
|
||||
new CameraValue("72", 0x6B, 72, PropertyID.Av),
|
||||
new CameraValue("76", 0x6C, 76, PropertyID.Av),
|
||||
new CameraValue("80", 0x6D, 80, PropertyID.Av),
|
||||
new CameraValue("91", 0x70, 91, PropertyID.Av),
|
||||
Invalid
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores Tv Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class TvValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
/// <summary>
|
||||
/// The Tv <see cref="CameraValue"/> of the "Auto" setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Tv);
|
||||
/// <summary>
|
||||
/// The Tv <see cref="CameraValue"/> of the "Bulb" setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Bulb = new CameraValue("Bulb", 0x0C, 0, PropertyID.Tv);
|
||||
/// <summary>
|
||||
/// The Tv <see cref="CameraValue"/> of an invalid setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Tv);
|
||||
|
||||
static TvValues()
|
||||
{
|
||||
values = new List<CameraValue>()
|
||||
{
|
||||
Auto,
|
||||
Bulb,
|
||||
new CameraValue("30\"", 0x10, 30, PropertyID.Tv),
|
||||
new CameraValue("25\"", 0x13, 25, PropertyID.Tv),
|
||||
new CameraValue("20\"", 0x14, 20, PropertyID.Tv),
|
||||
new CameraValue("20\" (1/3)", 0x15, 20, PropertyID.Tv),
|
||||
new CameraValue("15\"", 0x18, 15, PropertyID.Tv),
|
||||
new CameraValue("13\"", 0x1B, 13, PropertyID.Tv),
|
||||
new CameraValue("10\"", 0x1C, 10, PropertyID.Tv),
|
||||
new CameraValue("10\" (1/3)", 0x1D, 10, PropertyID.Tv),
|
||||
new CameraValue("8\"", 0x20, 8, PropertyID.Tv),
|
||||
new CameraValue("6\" (1/3)", 0x23, 6, PropertyID.Tv),
|
||||
new CameraValue("6\"", 0x24, 6, PropertyID.Tv),
|
||||
new CameraValue("5\"", 0x25, 5, PropertyID.Tv),
|
||||
new CameraValue("4\"", 0x28, 4, PropertyID.Tv),
|
||||
new CameraValue("3\"2", 0x2B, 3.2, PropertyID.Tv),
|
||||
new CameraValue("3\"", 0x2C, 3, PropertyID.Tv),
|
||||
new CameraValue("2\"5", 0x2D, 2.5, PropertyID.Tv),
|
||||
new CameraValue("2\"", 0x30, 2, PropertyID.Tv),
|
||||
new CameraValue("1\"6", 0x33, 1.6, PropertyID.Tv),
|
||||
new CameraValue("1\"5", 0x34, 1.5, PropertyID.Tv),
|
||||
new CameraValue("1\"3", 0x35, 1.3, PropertyID.Tv),
|
||||
new CameraValue("1\"", 0x38, 1, PropertyID.Tv),
|
||||
new CameraValue("0\"8", 0x3B, 0.8, PropertyID.Tv),
|
||||
new CameraValue("0\"7", 0x3C, 0.7, PropertyID.Tv),
|
||||
new CameraValue("0\"6", 0x3D, 0.6, PropertyID.Tv),
|
||||
new CameraValue("0\"5", 0x40, 0.5, PropertyID.Tv),
|
||||
new CameraValue("0\"4", 0x43, 0.4, PropertyID.Tv),
|
||||
new CameraValue("0\"3", 0x44, 0.3, PropertyID.Tv),
|
||||
new CameraValue("0\"3 (1/3)", 0x45, 0.3, PropertyID.Tv),
|
||||
new CameraValue("1/4", 0x48, 1 / 4d, PropertyID.Tv),
|
||||
new CameraValue("1/5", 0x4B, 1 / 5d, PropertyID.Tv),
|
||||
new CameraValue("1/6", 0x4C, 1 / 6d, PropertyID.Tv),
|
||||
new CameraValue("1/6 (1/3)", 0x4D, 1 / 6d, PropertyID.Tv),
|
||||
new CameraValue("1/8", 0x50, 1 / 8d, PropertyID.Tv),
|
||||
new CameraValue("1/10 (1/3)", 0x53, 1 / 10d, PropertyID.Tv),
|
||||
new CameraValue("1/10", 0x54, 1 / 10d, PropertyID.Tv),
|
||||
new CameraValue("1/13", 0x55, 1 / 13d, PropertyID.Tv),
|
||||
new CameraValue("1/15", 0x58, 1 / 15d, PropertyID.Tv),
|
||||
new CameraValue("1/20 (1/3)", 0x5B, 1 / 20d, PropertyID.Tv),
|
||||
new CameraValue("1/20", 0x5C, 1 / 20d, PropertyID.Tv),
|
||||
new CameraValue("1/25", 0x5D, 1 / 25d, PropertyID.Tv),
|
||||
new CameraValue("1/30", 0x60, 1 / 30d, PropertyID.Tv),
|
||||
new CameraValue("1/40", 0x63, 1 / 40d, PropertyID.Tv),
|
||||
new CameraValue("1/45", 0x64, 1 / 45d, PropertyID.Tv),
|
||||
new CameraValue("1/50", 0x65, 1 / 50d, PropertyID.Tv),
|
||||
new CameraValue("1/60", 0x68, 1 / 60d, PropertyID.Tv),
|
||||
new CameraValue("1/80", 0x6B, 1 / 80d, PropertyID.Tv),
|
||||
new CameraValue("1/90", 0x6C, 1 / 90d, PropertyID.Tv),
|
||||
new CameraValue("1/100", 0x6D, 1 / 100d, PropertyID.Tv),
|
||||
new CameraValue("1/125", 0x70, 1 / 125d, PropertyID.Tv),
|
||||
new CameraValue("1/160", 0x73, 1 / 160d, PropertyID.Tv),
|
||||
new CameraValue("1/180", 0x74, 1 / 180d, PropertyID.Tv),
|
||||
new CameraValue("1/200", 0x75, 1 / 200d, PropertyID.Tv),
|
||||
new CameraValue("1/250", 0x78, 1 / 150d, PropertyID.Tv),
|
||||
new CameraValue("1/320", 0x7B, 1 / 320d, PropertyID.Tv),
|
||||
new CameraValue("1/350", 0x7C, 1 / 350d, PropertyID.Tv),
|
||||
new CameraValue("1/400", 0x7D, 1 / 400d, PropertyID.Tv),
|
||||
new CameraValue("1/500", 0x80, 1 / 500d, PropertyID.Tv),
|
||||
new CameraValue("1/640", 0x83, 1 / 640d, PropertyID.Tv),
|
||||
new CameraValue("1/750", 0x84, 1 / 750d, PropertyID.Tv),
|
||||
new CameraValue("1/800", 0x85, 1 / 800d, PropertyID.Tv),
|
||||
new CameraValue("1/1000", 0x88, 1 / 1000d, PropertyID.Tv),
|
||||
new CameraValue("1/1250", 0x8B, 1 / 1250d, PropertyID.Tv),
|
||||
new CameraValue("1/1500", 0x8C, 1 / 1500d, PropertyID.Tv),
|
||||
new CameraValue("1/1600", 0x8D, 1 / 1600d, PropertyID.Tv),
|
||||
new CameraValue("1/2000", 0x90, 1 / 2000d, PropertyID.Tv),
|
||||
new CameraValue("1/2500", 0x93, 1 / 2500d, PropertyID.Tv),
|
||||
new CameraValue("1/3000", 0x94, 1 / 3000d, PropertyID.Tv),
|
||||
new CameraValue("1/3200", 0x95, 1 / 3200d, PropertyID.Tv),
|
||||
new CameraValue("1/4000", 0x98, 1 / 4000d, PropertyID.Tv),
|
||||
new CameraValue("1/5000", 0x9B, 1 / 5000d, PropertyID.Tv),
|
||||
new CameraValue("1/6000", 0x9C, 1 / 6000d, PropertyID.Tv),
|
||||
new CameraValue("1/6400", 0x9D, 1 / 6400d, PropertyID.Tv),
|
||||
new CameraValue("1/8000", 0xA0, 1 / 8000d, PropertyID.Tv),
|
||||
Invalid
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores ISO Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class ISOValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
/// <summary>
|
||||
/// The ISO <see cref="CameraValue"/> of the "Auto" setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Auto = new CameraValue("ISO Auto", 0x00000000, 0, PropertyID.ISO);
|
||||
/// <summary>
|
||||
/// The ISO <see cref="CameraValue"/> of an invalid setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ISO);
|
||||
|
||||
static ISOValues()
|
||||
{
|
||||
values = new List<CameraValue>()
|
||||
{
|
||||
Auto,
|
||||
new CameraValue("ISO 50", 0x00000040, 50, PropertyID.ISO),
|
||||
new CameraValue("ISO 100", 0x00000048, 100, PropertyID.ISO),
|
||||
new CameraValue("ISO 125", 0x0000004b, 125, PropertyID.ISO),
|
||||
new CameraValue("ISO 160", 0x0000004d, 160, PropertyID.ISO),
|
||||
new CameraValue("ISO 200", 0x00000050, 200, PropertyID.ISO),
|
||||
new CameraValue("ISO 250", 0x00000053, 250, PropertyID.ISO),
|
||||
new CameraValue("ISO 320", 0x00000055, 320, PropertyID.ISO),
|
||||
new CameraValue("ISO 400", 0x00000058, 400, PropertyID.ISO),
|
||||
new CameraValue("ISO 500", 0x0000005b, 500, PropertyID.ISO),
|
||||
new CameraValue("ISO 640", 0x0000005d, 640, PropertyID.ISO),
|
||||
new CameraValue("ISO 800", 0x00000060, 800, PropertyID.ISO),
|
||||
new CameraValue("ISO 1000", 0x00000063, 1000, PropertyID.ISO),
|
||||
new CameraValue("ISO 1250", 0x00000065, 1250, PropertyID.ISO),
|
||||
new CameraValue("ISO 1600", 0x00000068, 1600, PropertyID.ISO),
|
||||
new CameraValue("ISO 2000", 0x0000006b, 2000, PropertyID.ISO),
|
||||
new CameraValue("ISO 2500", 0x0000006d, 2500, PropertyID.ISO),
|
||||
new CameraValue("ISO 3200", 0x00000070, 3200, PropertyID.ISO),
|
||||
new CameraValue("ISO 4000", 0x00000073, 4000, PropertyID.ISO),
|
||||
new CameraValue("ISO 5000", 0x00000075, 5000, PropertyID.ISO),
|
||||
new CameraValue("ISO 6400", 0x00000078, 6400, PropertyID.ISO),
|
||||
new CameraValue("ISO 8000", 0x0000007b, 8000, PropertyID.ISO),
|
||||
new CameraValue("ISO 10000", 0x0000007d, 10000, PropertyID.ISO),
|
||||
new CameraValue("ISO 12800", 0x00000080, 12800, PropertyID.ISO),
|
||||
new CameraValue("ISO 16000", 0x00000083, 16000, PropertyID.ISO),
|
||||
new CameraValue("ISO 20000", 0x00000085, 20000, PropertyID.ISO),
|
||||
new CameraValue("ISO 25600", 0x00000088, 25600, PropertyID.ISO),
|
||||
new CameraValue("ISO 51200", 0x00000090, 51200, PropertyID.ISO),
|
||||
new CameraValue("ISO 102400", 0x00000098, 102400, PropertyID.ISO),
|
||||
Invalid
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores Exposure Compensation Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class ExpCompValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
/// <summary>
|
||||
/// The ExposureCompensation <see cref="CameraValue"/> of Zero
|
||||
/// </summary>
|
||||
public static readonly CameraValue Zero = new CameraValue("0", 0x00, 0, PropertyID.ExposureCompensation);
|
||||
/// <summary>
|
||||
/// The ExposureCompensation <see cref="CameraValue"/> of an invalid setting
|
||||
/// </summary>
|
||||
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ExposureCompensation);
|
||||
|
||||
static ExpCompValues()
|
||||
{
|
||||
values = new List<CameraValue>()
|
||||
{
|
||||
new CameraValue("+5", 0x28, 5, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+4 2/3", 0x25, 4 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+4 1/2", 0x24, 4 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+4 1/3", 0x23, 4 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+4", 0x20, 4, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+3 2/3", 0x1D, 3 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+3 1/2", 0x1C, 3 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+3 1/3", 0x1B, 3 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+3", 0x18, 3, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+2 2/3", 0x15, 2 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+2 1/2", 0x14, 2 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+2 1/3", 0x13, 2 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+2", 0x10, 2, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1 2/3", 0x0D, 1 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1 1/2", 0x0C, 1 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1 1/3", 0x0B, 1 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1", 0x08, 1, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+2/3", 0x05, 2 / 3d, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1/2", 0x04, 1 / 2d, PropertyID.ExposureCompensation),
|
||||
new CameraValue("+1/3", 0x03, 1 / 3d, PropertyID.ExposureCompensation),
|
||||
Zero,
|
||||
new CameraValue("–1/3", 0xFD, -1 / 3d, PropertyID.ExposureCompensation),
|
||||
new CameraValue("–1/2", 0xFC, -1 / 2d, PropertyID.ExposureCompensation),
|
||||
new CameraValue("–2/3", 0xFB, -2 / 3d, PropertyID.ExposureCompensation),
|
||||
new CameraValue("–1", 0xF8, -1, PropertyID.ExposureCompensation),
|
||||
new CameraValue("–1 1/3", 0xF5, -1 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–1 1/2", 0xF4, -1 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–1 2/3", 0xF3, -1 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–2", 0xF0, -2, PropertyID.ExposureCompensation),
|
||||
new CameraValue("–2 1/3", 0xED, -2 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–2 1/2", 0xEC, -2 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–2 2/3", 0xEB, -2 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("–3", 0xE8, -3, PropertyID.ExposureCompensation),
|
||||
new CameraValue("-3 1/3", 0xE5, -3 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-3 1/2", 0xE4, -3 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-3 2/3", 0xE3, -3 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-4", 0xE0, -4, PropertyID.ExposureCompensation),
|
||||
new CameraValue("-4 1/3", 0xDD, -4 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-4 1/2", 0xDC, -4 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-4 2/3", 0xDB, -4 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||
new CameraValue("-5", 0xD8, -5, PropertyID.ExposureCompensation),
|
||||
Invalid
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores AE Mode Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class AEModeValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
#pragma warning disable 1591
|
||||
|
||||
public static readonly CameraValue Program = new CameraValue("Program", 0, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Tv = new CameraValue("Tv", 1, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Av = new CameraValue("Av", 2, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Manual = new CameraValue("Manual", 3, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Bulb = new CameraValue("Bulb", 4, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue A_DEP = new CameraValue("A_DEP", 5, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue DEP = new CameraValue("DEP", 6, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Custom = new CameraValue("Custom", 7, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Lock = new CameraValue("Lock", 8, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Green = new CameraValue("Green", 9, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue NightPortrait = new CameraValue("NightPortrait", 10, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Sports = new CameraValue("Sports", 11, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Portrait = new CameraValue("Portrait", 12, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Landscape = new CameraValue("Landscape", 13, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Closeup = new CameraValue("Closeup", 14, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue FlashOff = new CameraValue("FlashOff", 15, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Custom2 = new CameraValue("Custom2", 16, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Custom3 = new CameraValue("Custom3", 17, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue CreativeAuto = new CameraValue("CreativeAuto", 19, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie = new CameraValue("Movie", 20, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue PhotoInMovie = new CameraValue("PhotoInMovie", 21, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue SceneIntelligentAuto = new CameraValue("SceneIntelligentAuto", 22, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Scene = new CameraValue("Scene", 25, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue NightScenes = new CameraValue("NightScenes", 23, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue BacklitScenes = new CameraValue("BacklitScenes", 24, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Children = new CameraValue("Children", 26, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Food = new CameraValue("Food", 27, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue CandlelightPortraits = new CameraValue("CandlelightPortraits", 28, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue CreativeFilter = new CameraValue("CreativeFilter", 29, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue RoughMonoChrome = new CameraValue("RoughMonoChrome", 30, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue SoftFocus = new CameraValue("SoftFocus", 31, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue ToyCamera = new CameraValue("ToyCamera", 32, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Fisheye = new CameraValue("Fisheye", 33, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue WaterColor = new CameraValue("WaterColor", 34, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Miniature = new CameraValue("Miniature", 35, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Hdr_Standard = new CameraValue("Hdr_Standard", 36, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Hdr_Vivid = new CameraValue("Hdr_Vivid", 37, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Hdr_Bold = new CameraValue("Hdr_Bold", 38, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Hdr_Embossed = new CameraValue("Hdr_Embossed", 39, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie_Fantasy = new CameraValue("Movie_Fantasy", 40, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie_Old = new CameraValue("Movie_Old", 41, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie_Memory = new CameraValue("Movie_Memory", 42, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie_DirectMono = new CameraValue("Movie_DirectMono", 43, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Movie_Mini = new CameraValue("Movie_Mini", 44, 0, PropertyID.AEMode);
|
||||
public static readonly CameraValue Unknown = new CameraValue("Unknown", unchecked((int)0xFFFFFFFF), 0, PropertyID.AEMode);
|
||||
|
||||
#pragma warning restore 1591
|
||||
|
||||
static AEModeValues()
|
||||
{
|
||||
values = new List<CameraValue>();
|
||||
values.Add(Program);
|
||||
values.Add(Tv);
|
||||
values.Add(Av);
|
||||
values.Add(Manual);
|
||||
values.Add(Bulb);
|
||||
values.Add(A_DEP);
|
||||
values.Add(DEP);
|
||||
values.Add(Custom);
|
||||
values.Add(Lock);
|
||||
values.Add(Green);
|
||||
values.Add(NightPortrait);
|
||||
values.Add(Sports);
|
||||
values.Add(Portrait);
|
||||
values.Add(Landscape);
|
||||
values.Add(Closeup);
|
||||
values.Add(FlashOff);
|
||||
values.Add(Custom2);
|
||||
values.Add(Custom3);
|
||||
values.Add(CreativeAuto);
|
||||
values.Add(Movie);
|
||||
values.Add(PhotoInMovie);
|
||||
values.Add(SceneIntelligentAuto);
|
||||
values.Add(Scene);
|
||||
values.Add(NightScenes);
|
||||
values.Add(BacklitScenes);
|
||||
values.Add(Children);
|
||||
values.Add(Food);
|
||||
values.Add(CandlelightPortraits);
|
||||
values.Add(CreativeFilter);
|
||||
values.Add(RoughMonoChrome);
|
||||
values.Add(SoftFocus);
|
||||
values.Add(ToyCamera);
|
||||
values.Add(Fisheye);
|
||||
values.Add(WaterColor);
|
||||
values.Add(Miniature);
|
||||
values.Add(Hdr_Standard);
|
||||
values.Add(Hdr_Vivid);
|
||||
values.Add(Hdr_Bold);
|
||||
values.Add(Hdr_Embossed);
|
||||
values.Add(Movie_Fantasy);
|
||||
values.Add(Movie_Old);
|
||||
values.Add(Movie_Memory);
|
||||
values.Add(Movie_DirectMono);
|
||||
values.Add(Movie_Mini);
|
||||
values.Add(Unknown);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores Metering Mode Values and provides methods to get those values
|
||||
/// </summary>
|
||||
public sealed class MeteringModeValues : ValueBase
|
||||
{
|
||||
/// <summary>
|
||||
/// All values for this property
|
||||
/// </summary>
|
||||
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||
private static List<CameraValue> values;
|
||||
|
||||
#pragma warning disable 1591
|
||||
|
||||
public static readonly CameraValue Spot = new CameraValue("Spot", 1, 0, PropertyID.MeteringMode);
|
||||
public static readonly CameraValue Evaluative = new CameraValue("Evaluative", 3, 0, PropertyID.MeteringMode);
|
||||
public static readonly CameraValue Partial = new CameraValue("Partial", 4, 0, PropertyID.MeteringMode);
|
||||
public static readonly CameraValue CenterWeightedAveraging = new CameraValue("Center-weighted averaging", 5, 0, PropertyID.MeteringMode);
|
||||
public static readonly CameraValue NotValid = new CameraValue("Not valid", unchecked((int)0xFFFFFFFF), 0, PropertyID.MeteringMode);
|
||||
|
||||
#pragma warning restore 1591
|
||||
|
||||
static MeteringModeValues()
|
||||
{
|
||||
values = new List<CameraValue>();
|
||||
values.Add(Spot);
|
||||
values.Add(Evaluative);
|
||||
values.Add(Partial);
|
||||
values.Add(CenterWeightedAveraging);
|
||||
values.Add(NotValid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from an int.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of the value to get</param>
|
||||
/// <returns>The CameraValue with given int representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(int value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a string.
|
||||
/// It has to be an exact match, otherwise an exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="value">The ID of value to get</param>
|
||||
/// <returns>The CameraValue with given string representation</returns>
|
||||
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||
public static CameraValue GetValue(string value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value from a double.
|
||||
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to get</param>
|
||||
/// <returns>The CameraValue with given double representation</returns>
|
||||
public static CameraValue GetValue(double value)
|
||||
{
|
||||
return GetValue(value, values);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/CamBooth/EDSDKLib/EDSDKLib.csproj
Normal file
65
src/CamBooth/EDSDKLib/EDSDKLib.csproj
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{15E99248-6161-46A4-9183-609CA62406A6}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>EDSDKLib</RootNamespace>
|
||||
<AssemblyName>EDSDKLib</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<LangVersion>8</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\EDSDKLib.xml</DocumentationFile>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="API\Base\Camera.cs" />
|
||||
<Compile Include="API\Base\CanonAPI.cs" />
|
||||
<Compile Include="API\Helper\ApiThread.cs" />
|
||||
<Compile Include="API\Helper\CameraValue.cs" />
|
||||
<Compile Include="API\Helper\Delegates.cs" />
|
||||
<Compile Include="API\Helper\ExceptionHandling.cs" />
|
||||
<Compile Include="API\Helper\IO.cs" />
|
||||
<Compile Include="API\Helper\STAThread.cs" />
|
||||
<Compile Include="API\Helper\ValueCollections.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SDK\SDKDelegates.cs" />
|
||||
<Compile Include="SDK\SDKEnums.cs" />
|
||||
<Compile Include="SDK\SDKMethods.cs" />
|
||||
<Compile Include="SDK\SDKStructs.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
15
src/CamBooth/EDSDKLib/Properties/AssemblyInfo.cs
Normal file
15
src/CamBooth/EDSDKLib/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
[assembly: AssemblyTitle("EDSDKLib")]
|
||||
[assembly: AssemblyDescription("Canon SDK wrapper library")]
|
||||
[assembly: AssemblyProduct("EDSDKLib")]
|
||||
[assembly: AssemblyCopyright("Copyright © Johannes Bildstein 2016")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: Guid("15e99248-6161-46a4-9183-609ca62406a6")]
|
||||
|
||||
[assembly: AssemblyVersion("1.1.1.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.1.0")]
|
||||
44
src/CamBooth/EDSDKLib/SDK/SDKDelegates.cs
Normal file
44
src/CamBooth/EDSDKLib/SDK/SDKDelegates.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace EOSDigital.SDK
|
||||
{
|
||||
/// <summary>
|
||||
/// A delegate for progress.
|
||||
/// </summary>
|
||||
/// <param name="inPercent">The progress. A value between 0 and 100</param>
|
||||
/// <param name="inContext">Reference to the object the progress is about</param>
|
||||
/// <param name="outCancel">Pass true to cancel the underlying process</param>
|
||||
/// <returns></returns>
|
||||
public delegate ErrorCode SDKProgressCallback(int inPercent, IntPtr inContext, ref bool outCancel);
|
||||
/// <summary>
|
||||
/// A delegate for property events.
|
||||
/// </summary>
|
||||
/// <param name="inEvent">The property event ID</param>
|
||||
/// <param name="inPropertyID">The property ID</param>
|
||||
/// <param name="inParameter">A parameter for additional information</param>
|
||||
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||
/// <returns>Any of the SDK errors</returns>
|
||||
public delegate ErrorCode SDKPropertyEventHandler(PropertyEventID inEvent, PropertyID inPropertyID, int inParameter, IntPtr inContext);
|
||||
/// <summary>
|
||||
/// A delegate for object events.
|
||||
/// </summary>
|
||||
/// <param name="inEvent">The object event ID</param>
|
||||
/// <param name="inRef">A pointer to the object that has changed</param>
|
||||
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||
/// <returns>Any of the SDK errors</returns>
|
||||
public delegate ErrorCode SDKObjectEventHandler(ObjectEventID inEvent, IntPtr inRef, IntPtr inContext);
|
||||
/// <summary>
|
||||
/// A delegate for state events.
|
||||
/// </summary>
|
||||
/// <param name="inEvent">The state event ID</param>
|
||||
/// <param name="inParameter">A parameter for additional information</param>
|
||||
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||
/// <returns>Any of the SDK errors</returns>
|
||||
public delegate ErrorCode SDKStateEventHandler(StateEventID inEvent, int inParameter, IntPtr inContext);
|
||||
/// <summary>
|
||||
/// A delegate to inform of an added camera.
|
||||
/// </summary>
|
||||
/// <param name="inContext">A reference to the added camera</param>
|
||||
/// <returns>Any of the SDK errors</returns>
|
||||
public delegate ErrorCode SDKCameraAddedHandler(IntPtr inContext);
|
||||
}
|
||||
1572
src/CamBooth/EDSDKLib/SDK/SDKEnums.cs
Normal file
1572
src/CamBooth/EDSDKLib/SDK/SDKEnums.cs
Normal file
File diff suppressed because it is too large
Load Diff
1521
src/CamBooth/EDSDKLib/SDK/SDKMethods.cs
Normal file
1521
src/CamBooth/EDSDKLib/SDK/SDKMethods.cs
Normal file
File diff suppressed because it is too large
Load Diff
1622
src/CamBooth/EDSDKLib/SDK/SDKStructs.cs
Normal file
1622
src/CamBooth/EDSDKLib/SDK/SDKStructs.cs
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user