Add project files.

This commit is contained in:
Daniel Clark
2022-11-01 15:26:08 +00:00
parent daa7b59f22
commit 7e4f880821
408 changed files with 16863 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-rc.2.22472.3" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0-rc.2.22472.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Media\Capture\Capture.csproj" />
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
</Project>
+19
View File
@@ -0,0 +1,19 @@
using Microsoft.Extensions.Configuration;
using System.Collections.ObjectModel;
namespace TheXamlGuy.Framework.Camera;
public class CameraBuilder : ICameraBuilder
{
private readonly List<ICameraBuilderConfiguration> configurations = new();
public IReadOnlyCollection<ICameraBuilderConfiguration> Configurations => new ReadOnlyCollection<ICameraBuilderConfiguration>(configurations);
public ICameraBuilderConfiguration<TConfiguration> Add<TConfiguration>(IConfiguration configuration) where TConfiguration : IRemoteCameraConfiguration, new()
{
CameraBuilderConfiguration<TConfiguration>? builderConfiguration = new(configuration);
configurations.Add(builderConfiguration);
return builderConfiguration;
}
}
@@ -0,0 +1,16 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace TheXamlGuy.Framework.Camera;
public class CameraBuilderConfiguration<TConfiguration> : ICameraBuilderConfiguration<TConfiguration> where TConfiguration : INamedCameraConfiguration, new()
{
private readonly IConfiguration configuration;
public CameraBuilderConfiguration(IConfiguration configuration)
{
this.configuration = configuration;
}
public Func<IServiceProvider, ICameraContext> Factory => (IServiceProvider provider) => provider.GetService<ICameraFactory>()!.Create(configuration.Get<TConfiguration>());
}
+48
View File
@@ -0,0 +1,48 @@
using TheXamlGuy.Framework.Core;
using TheXamlGuy.Media.Capture;
namespace TheXamlGuy.Framework.Camera;
public class CameraContext : ICameraContext
{
private readonly IEventAggregator eventAggregator;
private ILowLagPhotoCapture? lowLagPhotoCapture;
private IMediaCapture? mediaCapture;
public CameraContext(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
public async Task InitializeAsync()
{
IReadOnlyList<IMediaFrameSource> sourceGroups = await MediaFrameSource.FindAllAsync();
if (sourceGroups.FirstOrDefault(x => x.DisplayName.Contains("USB", StringComparison.InvariantCultureIgnoreCase)) is IMediaFrameSource source)
{
if (source.SupportedFormats.OrderByDescending(x => x.Size.Width & x.Size.Height).FirstOrDefault() is MediaFrameFormat bestSupportedFormat)
{
source.SetFormat(bestSupportedFormat);
}
MediaCaptureInitializationSettings settings = new()
{
Source = source
};
mediaCapture = new MediaCapture();
mediaCapture.Initialize(settings);
lowLagPhotoCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync();
eventAggregator.SubscribeUI<Capture>(OnCapture);
}
}
private async void OnCapture(Capture args)
{
if (lowLagPhotoCapture is not null)
{
await lowLagPhotoCapture.CaptureAsync();
}
}
}
+34
View File
@@ -0,0 +1,34 @@
using TheXamlGuy.Framework.Core;
namespace TheXamlGuy.Framework.Camera;
public class CameraFactory : ICameraFactory
{
private readonly Dictionary<INamedCameraConfiguration, ICameraContext> cache = new();
private readonly IServiceFactory factory;
public CameraFactory(IServiceFactory factory)
{
this.factory = factory;
}
public ICameraContext Create(INamedCameraConfiguration configuration)
{
if (cache.TryGetValue(configuration, out ICameraContext? context))
{
return context;
}
if (configuration is IRemoteCameraConfiguration)
{
context = factory.Create<RemoteCameraContext>();
}
else
{
context = factory.Create<CameraContext>();
}
cache.Add(configuration, context);
return context;
}
}
+3
View File
@@ -0,0 +1,3 @@
namespace TheXamlGuy.Framework.Camera;
public record Capture;
+12
View File
@@ -0,0 +1,12 @@
using System.Drawing;
namespace TheXamlGuy.Framework.Camera;
public record Captured
{
public Bitmap? Photo { get; init; }
public int Width { get; init; }
public int Height { get; init; }
}
+10
View File
@@ -0,0 +1,10 @@
using Microsoft.Extensions.Configuration;
namespace TheXamlGuy.Framework.Camera;
public interface ICameraBuilder
{
IReadOnlyCollection<ICameraBuilderConfiguration> Configurations { get; }
ICameraBuilderConfiguration<TConfiguration> Add<TConfiguration>(IConfiguration configuration) where TConfiguration : IRemoteCameraConfiguration, new();
}
@@ -0,0 +1,11 @@
namespace TheXamlGuy.Framework.Camera;
public interface ICameraBuilderConfiguration
{
Func<IServiceProvider, ICameraContext> Factory { get; }
}
public interface ICameraBuilderConfiguration<TConfiguration> : ICameraBuilderConfiguration where TConfiguration : INamedCameraConfiguration, new()
{
}
+5
View File
@@ -0,0 +1,5 @@
namespace TheXamlGuy.Framework.Camera;
public interface ICameraConfiguration : INamedCameraConfiguration
{
}
+8
View File
@@ -0,0 +1,8 @@
using TheXamlGuy.Framework.Core;
namespace TheXamlGuy.Framework.Camera;
public interface ICameraContext : IInitializer
{
}
+6
View File
@@ -0,0 +1,6 @@
namespace TheXamlGuy.Framework.Camera;
public interface ICameraFactory
{
ICameraContext Create(INamedCameraConfiguration configuration);
}
@@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
namespace TheXamlGuy.Framework.Camera;
public static class IHostBuilderExtensions
{
public static IHostBuilder ConfigureCamera(this IHostBuilder hostBuilder, Action<HostBuilderContext, ICameraBuilder> builderDelegate)
{
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
{
CameraBuilder? builder = new();
builderDelegate.Invoke(hostBuilderContext, builder);
serviceCollection.TryAddSingleton<ICameraFactory, CameraFactory>();
foreach (ICameraBuilderConfiguration configuration in builder.Configurations)
{
serviceCollection.AddSingleton(provider => configuration.Factory.Invoke(provider));
}
});
return hostBuilder;
}
}
@@ -0,0 +1,6 @@
namespace TheXamlGuy.Framework.Camera;
public interface INamedCameraConfiguration
{
string Name { get; }
}
@@ -0,0 +1,5 @@
namespace TheXamlGuy.Framework.Camera;
public interface IRemoteCameraConfiguration : INamedCameraConfiguration
{
}
@@ -0,0 +1,9 @@
using System.Diagnostics.CodeAnalysis;
namespace TheXamlGuy.Framework.Camera;
public class RemoteCameraConfiguration : IRemoteCameraConfiguration
{
[NotNull]
public string? Name { get; set; }
}
+51
View File
@@ -0,0 +1,51 @@
using TheXamlGuy.Framework.Core;
using TheXamlGuy.Media.Capture;
namespace TheXamlGuy.Framework.Camera;
public class RemoteCameraContext : ICameraContext
{
private readonly IEventAggregator eventAggregator;
private ILowLagPhotoCapture? lowLagPhotoCapture;
private IRemoteMediaCapture? mediaCapture;
public RemoteCameraContext(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
public async Task InitializeAsync()
{
IReadOnlyList<IRemoteMediaFrameSource> sourceGroups = await RemoteMediaFrameSource.FindAllAsync();
if (sourceGroups.FirstOrDefault(x => x.DisplayName.Contains("DSC-HX60", StringComparison.InvariantCultureIgnoreCase)) is IRemoteMediaFrameSource source)
{
RemoteMediaCaptureInitializationSettings settings = new()
{
Source = source
};
mediaCapture = new RemoteMediaCapture();
mediaCapture.Initialize(settings);
lowLagPhotoCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync();
eventAggregator.SubscribeUI<Capture>(OnCapture);
}
}
private async void OnCapture(Capture args)
{
if (lowLagPhotoCapture is not null)
{
if (await lowLagPhotoCapture.CaptureAsync() is CapturedPhoto capturedPhoto)
{
eventAggregator.Publish(new Captured
{
Photo = capturedPhoto.Photo,
Width = capturedPhoto.Width,
Height = capturedPhoto.Height
});
}
}
}
}