diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-01-28 19:40:35 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-01-28 19:40:35 +0200 |
| commit | 7e8ff4c3ca798d426eb6f381c5312a747f1bb800 (patch) | |
| tree | cf9702617f9771412c78294ad742c308007ebce1 /Software/Visual_Studio | |
| parent | 10eec8df1dfce197b31d51cfa49746b0ce07a5e5 (diff) | |
| download | Tango-7e8ff4c3ca798d426eb6f381c5312a747f1bb800.tar.gz Tango-7e8ff4c3ca798d426eb6f381c5312a747f1bb800.zip | |
Implemented all color spaces on segment brushes (simple conversion).
Embedded ColorMine library as a SideChain.
Diffstat (limited to 'Software/Visual_Studio')
34 files changed, 2556 insertions, 31 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopCMYKToColorConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopCMYKToColorConverter.cs new file mode 100644 index 000000000..e21da8fbc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopCMYKToColorConverter.cs @@ -0,0 +1,53 @@ +using ColorMine.ColorSpaces; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.DAL.Observables; + +namespace Tango.MachineStudio.Developer.Converters +{ + public class BrushStopCMYKToColorConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + Cmyk cmyk = new Cmyk(); + + cmyk.C = System.Convert.ToDouble(values[0]) / 100d; + cmyk.M = System.Convert.ToDouble(values[1]) / 100d; + cmyk.Y = System.Convert.ToDouble(values[2]) / 100d; + cmyk.K = System.Convert.ToDouble(values[3]) / 100d; + + IRgb rgb = cmyk.ToRgb(); + + return Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + } + catch + { + return null; + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + try + { + Color color = (Color)value; + Rgb rgb = new Rgb(color.R, color.G, color.B); + Cmyk cmyk = rgb.To<Cmyk>(); + + return new object[] { cmyk.C * 100, cmyk.M * 100, cmyk.Y * 100, cmyk.K * 100 }; + } + catch + { + return null; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopLabToColorConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopLabToColorConverter.cs new file mode 100644 index 000000000..6c6d7959e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopLabToColorConverter.cs @@ -0,0 +1,52 @@ +using ColorMine.ColorSpaces; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.DAL.Observables; + +namespace Tango.MachineStudio.Developer.Converters +{ + public class BrushStopLabToColorConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + Lab lab = new Lab(); + + lab.L = System.Convert.ToDouble(values[0]); + lab.A = System.Convert.ToDouble(values[1]); + lab.B = System.Convert.ToDouble(values[2]); + + IRgb rgb = lab.ToRgb(); + + return Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + } + catch + { + return null; + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + try + { + Color color = (Color)value; + Rgb rgb = new Rgb(color.R, color.G, color.B); + Lab cmyk = rgb.To<Lab>(); + + return new object[] { cmyk.L, cmyk.A, cmyk.B }; + } + catch + { + return null; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopToColorConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopToColorConverter.cs new file mode 100644 index 000000000..5db8d03c0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopToColorConverter.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.DAL.Observables; + +namespace Tango.MachineStudio.Developer.Converters +{ + public class BrushStopToColorConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + double r = System.Convert.ToDouble(values[0]); + double g = System.Convert.ToDouble(values[1]); + double b = System.Convert.ToDouble(values[2]); + + return Color.FromRgb((byte)r, (byte)g, (byte)b); + } + catch + { + return null; + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + try + { + Color color = (Color)value; + return new object[] { color.R, color.G, color.B }; + } + catch + { + return null; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj index dc3f9947a..2bbd57b86 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Tango.MachineStudio.Developer.csproj @@ -71,6 +71,9 @@ <Reference Include="PresentationFramework" /> </ItemGroup> <ItemGroup> + <Compile Include="Converters\BrushStopLabToColorConverter.cs" /> + <Compile Include="Converters\BrushStopCMYKToColorConverter.cs" /> + <Compile Include="Converters\BrushStopToColorConverter.cs" /> <Compile Include="Converters\DbRmlViewToEntityConverter.cs" /> <Compile Include="DeveloperModule.cs" /> <Compile Include="ViewModelLocator.cs" /> @@ -117,10 +120,18 @@ </None> </ItemGroup> <ItemGroup> + <ProjectReference Include="..\..\..\SideChains\ColorMine\ColorMine.csproj"> + <Project>{37e4ceab-b54b-451f-b535-04cf7da9c459}</Project> + <Name>ColorMine</Name> + </ProjectReference> <ProjectReference Include="..\..\..\SideChains\RealTimeGraphEx\RealTimeGraphEx.csproj"> <Project>{b9ae25d6-be35-492f-9079-21a7f3e6f7cc}</Project> <Name>RealTimeGraphEx</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.ColorPicker\Tango.ColorPicker.csproj"> + <Project>{a2f5af44-29ff-45d6-9d25-ecda5cce88b5}</Project> + <Name>Tango.ColorPicker</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj"> <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml index e7aa85fb8..73c00fea8 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml @@ -7,6 +7,7 @@ xmlns:global="clr-namespace:Tango.MachineStudio.Developer" xmlns:dragAndDrop="clr-namespace:Tango.DragAndDrop;assembly=Tango.DragAndDrop" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker" xmlns:db="clr-namespace:Tango.MachineStudio.DB.Views.DBViews;assembly=Tango.MachineStudio.DB" xmlns:commonControls="clr-namespace:Tango.MachineStudio.Common.Controls;assembly=Tango.MachineStudio.Common" xmlns:designer="clr-namespace:Tango.MachineStudio.MachineDesigner.Views;assembly=Tango.MachineStudio.MachineDesigner" @@ -22,7 +23,7 @@ <UserControl.Resources> <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}"> - <Setter Property="mahapps:ControlsHelper.HeaderFontSize" Value="18" /> + <Setter Property="mahapps:ControlsHelper.HeaderFontSize" Value="14" /> <Setter Property="Margin" Value="2" /> </Style> @@ -31,6 +32,9 @@ <converters:NullObjectToBooleanConverter x:Key="NullObjectToBooleanConverter"></converters:NullObjectToBooleanConverter> <converters:GreaterThanToBooleanConverter x:Key="GreaterThanToBooleanConverter"></converters:GreaterThanToBooleanConverter> <converters:SmallerThanToBooleanConverter x:Key="SmallerThanToBooleanConverter"></converters:SmallerThanToBooleanConverter> + <localConverters:BrushStopToColorConverter x:Key="BrushStopToColorConverter" /> + <localConverters:BrushStopCMYKToColorConverter x:Key="BrushStopCMYKToColorConverter" /> + <localConverters:BrushStopLabToColorConverter x:Key="BrushStopLabToColorConverter" /> <SolidColorBrush x:Key="SideBarBackground" Color="#F9F9F9"> @@ -291,7 +295,7 @@ <Grid> <Grid.RowDefinitions> <RowDefinition Height="234*"/> - <RowDefinition Height="161*"/> + <RowDefinition x:Name="graphRowDefinition" Height="161*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="173*"/> @@ -311,10 +315,10 @@ <Rectangle VerticalAlignment="Bottom" StrokeDashArray="7" StrokeThickness="1" Stroke="Silver" Margin="0 8 0 0"></Rectangle> </StackPanel> <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right"> - <Button Command="{Binding RemoveJobCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Remove Segment"> + <Button Command="{Binding RemoveJobCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Remove Job"> <materialDesign:PackIcon Kind="MinusCircleOutline" Width="24" Height="24"></materialDesign:PackIcon> </Button> - <Button Command="{Binding AddJobCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Add Segment"> + <Button Command="{Binding AddJobCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Add Job"> <materialDesign:PackIcon Kind="PlusCircleOutline" Width="24" Height="24"></materialDesign:PackIcon> </Button> </StackPanel> @@ -488,10 +492,10 @@ <Grid DockPanel.Dock="Bottom"> <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right"> - <Button Command="{Binding RemoveBrushStopCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Remove Segment"> + <Button Command="{Binding RemoveBrushStopCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Remove Color"> <materialDesign:PackIcon Kind="MinusCircleOutline" Width="24" Height="24"></materialDesign:PackIcon> </Button> - <Button Command="{Binding AddBrushStopCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Add Segment"> + <Button Command="{Binding AddBrushStopCommand}" Margin="5" Style="{StaticResource MaterialDesignFlatButton}" Padding="0" ToolTip="Add Color"> <materialDesign:PackIcon Kind="PlusCircleOutline" Width="24" Height="24"></materialDesign:PackIcon> </Button> </StackPanel> @@ -527,31 +531,189 @@ </Border.Style> <Grid> <DockPanel> - <StackPanel DockPanel.Dock="Left" VerticalAlignment="Center"> - <ItemsControl ItemsSource="{Binding InkVolumes}" VerticalAlignment="Center"> - <ItemsControl.ItemsPanel> - <ItemsPanelTemplate> - <StackPanel VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> - </ItemsPanelTemplate> - </ItemsControl.ItemsPanel> - <ItemsControl.ItemTemplate> - <DataTemplate> - <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0"> - <Border.BorderBrush> - <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> - </Border.BorderBrush> - <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0.0" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> - <mahapps:NumericUpDown.Resources> - <Style TargetType="TextBox"> + <ContentControl DockPanel.Dock="Left"> + <ContentControl.Style> + <Style TargetType="ContentControl"> + <Setter Property="Content"> + <Setter.Value> + <Rectangle/> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding ColorSpace.Name}" Value="Volume"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel VerticalAlignment="Center"> + <ItemsControl ItemsSource="{Binding InkVolumes}" VerticalAlignment="Center"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0"> + <Border.BorderBrush> + <SolidColorBrush Color="{Binding IdsPack.LiquidType.Color,Converter={StaticResource ColorToIntegerConverter}}"></SolidColorBrush> + </Border.BorderBrush> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Volume, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0.0" HideUpDownButtons="True" Minimum="0" Maximum="1000" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ColorSpace.Name}" Value="RGB"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel Orientation="Horizontal"> + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="#FF6F6F"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Red, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="255" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="False" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="#92FF92"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Green, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="255" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="False" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="#3C7EF4"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Blue, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="255" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="False" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <colorPicker:ColorPickerCombo Margin="30 0 0 0" VerticalAlignment="Center" Width="100" BorderBrush="{StaticResource AccentColorBrush}" Background="White"> + <colorPicker:ColorPickerCombo.SelectedColor> + <MultiBinding Converter="{StaticResource BrushStopToColorConverter}"> + <Binding Path="Red"></Binding> + <Binding Path="Green"></Binding> + <Binding Path="Blue"></Binding> + </MultiBinding> + </colorPicker:ColorPickerCombo.SelectedColor> + </colorPicker:ColorPickerCombo> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ColorSpace.Name}" Value="CMYK"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel Orientation="Horizontal"> + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="Cyan"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Cyan, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="Magenta"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Magenta, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="Yellow"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Yellow, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="Black"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding Black, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0" HideUpDownButtons="True" Minimum="0" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Rectangle Margin="30 0 0 0" Width="50" Height="50" StrokeThickness="1" Stroke="Gray"> + <Rectangle.Fill> + <SolidColorBrush> + <SolidColorBrush.Color> + <MultiBinding Converter="{StaticResource BrushStopCMYKToColorConverter}"> + <Binding Path="Cyan"></Binding> + <Binding Path="Magenta"></Binding> + <Binding Path="Yellow"></Binding> + <Binding Path="Black"></Binding> + </MultiBinding> + </SolidColorBrush.Color> + </SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + <DataTrigger Binding="{Binding ColorSpace.Name}" Value="LAB"> + <Setter Property="Content"> + <Setter.Value> + <StackPanel Orientation="Horizontal"> + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="Gray"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding L, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0.0" HideUpDownButtons="True" Minimum="-100" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="#FF8A8A"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding A, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0.0" HideUpDownButtons="True" Minimum="-100" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Border BorderThickness="1" Width="50" Height="50" CornerRadius="50" Margin="10 0 0 0" BorderBrush="#FFFF8A"> + <mahapps:NumericUpDown FontSize="14" FontFamily="digital-7" HorizontalAlignment="Center" Value="{Binding B, Mode=TwoWay}" Background="Transparent" Width="40" StringFormat="0.0" HideUpDownButtons="True" Minimum="-100" Maximum="100" InterceptArrowKeys="True" BorderThickness="0" InterceptMouseWheel="True" HasDecimals="True" HorizontalContentAlignment="Center"> + <mahapps:NumericUpDown.Resources> + <Style TargetType="TextBox"/> + </mahapps:NumericUpDown.Resources> + </mahapps:NumericUpDown> + </Border> + + <Rectangle Margin="30 0 0 0" Width="50" Height="50" StrokeThickness="1" Stroke="Gray"> + <Rectangle.Fill> + <SolidColorBrush> + <SolidColorBrush.Color> + <MultiBinding Converter="{StaticResource BrushStopLabToColorConverter}"> + <Binding Path="L"></Binding> + <Binding Path="A"></Binding> + <Binding Path="B"></Binding> + </MultiBinding> + </SolidColorBrush.Color> + </SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </StackPanel> + </Setter.Value> + </Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </ContentControl.Style> + </ContentControl> - </Style> - </mahapps:NumericUpDown.Resources> - </mahapps:NumericUpDown> - </Border> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - </StackPanel> <Grid DockPanel.Dock="Right"> <Border Style="{StaticResource JobFieldBorder}"> <StackPanel Margin="5" Width="140"> @@ -772,6 +934,11 @@ </LinearGradientBrush> </Border.Background> + + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 0 120 0"> + <ToggleButton x:Name="chkGraphs" IsChecked="True"></ToggleButton> + <TextBlock VerticalAlignment="Center" Margin="5 -1 0 0" Foreground="Gray">Show Graphs</TextBlock> + </StackPanel> </Border> <dragAndDrop:DraggingSurface x:Name="draggingSurface" /> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml.cs index 9eeff4975..c4e853433 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml.cs @@ -42,6 +42,9 @@ namespace Tango.MachineStudio.Developer.Views { _vm = DataContext as MainViewVM; }; + + chkGraphs.Checked += (x, y) => { graphRowDefinition.Height = new GridLength(161, GridUnitType.Star); }; + chkGraphs.Unchecked += (x, y) => { graphRowDefinition.Height = new GridLength(80, GridUnitType.Pixel); }; } private void OnDropAvailableSensor(object sender, DropEventArgs e) diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorMine.csproj b/Software/Visual_Studio/SideChains/ColorMine/ColorMine.csproj new file mode 100644 index 000000000..b47e55306 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorMine.csproj @@ -0,0 +1,29 @@ +<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0"> + <PropertyGroup> + <TargetFrameworks>net45;netstandard1.6</TargetFrameworks> + <AssemblyTitle>ColorMine</AssemblyTitle> + <RootNamespace>ColorMine</RootNamespace> + <Version>1.2.0</Version> + <FileVersion>1.2.0</FileVersion> + <Description>.NET library that makes converting betwewen color spaces and comparing colors easy</Description> + <Company>Continuous Automation LLC</Company> + <Copyright>Copyright © 2017 Joe Zack</Copyright> + </PropertyGroup> + + <ItemGroup> + <!-- The T4 TextTemplatingFileGenerator Service--> + <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> + </ItemGroup> + + <ItemGroup> + <None Update="ColorSpaces\ColorSpaces.tt"> + <Generator>TextTemplatingFileGenerator</Generator> + <LastGenOutput>ColorSpaces.cs</LastGenOutput> + </None> + <Compile Update="ColorSpaces\ColorSpaces.cs"> + <DesignTime>True</DesignTime> + <AutoGen>True</AutoGen> + <DependentUpon>ColorSpaces.tt</DependentUpon> + </Compile> + </ItemGroup> +</Project> diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorMine.nuspec b/Software/Visual_Studio/SideChains/ColorMine/ColorMine.nuspec new file mode 100644 index 000000000..a8a40c98d --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorMine.nuspec @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> + <metadata> + <id>ColorMine</id> + <version>1.1.3.0</version> + <title>ColorMine</title> + <authors>Joe Zack</authors> + <licenseUrl>http://opensource.org/licenses/MIT</licenseUrl> + <projectUrl>https://github.com/THEjoezack/ColorMine</projectUrl> + <requireLicenseAcceptance>false</requireLicenseAcceptance> + <description>Open source library that makes converting and comparing colors easy. + + ## Supported Color Models: + * CMY + * CMYK + * HSL + * HSB + * HSV + * CIE L*AB + * Hunter LAB + * LCH + * LUV + * sRGB + * XYZ + * YXY + + ## Supported Comparisons + * CIE76 + * CMC l:c + * CIE94 + * CIE2000 + + Demonstrations at http://colormine.org.</description> + <releaseNotes>1.1.3.0 - 04/02/2014 +Bumped .Net version down to 4.0 +Fixed HSB Calcuations + +1.1.2.1 - 03/12/2014 +Now strongly signed + +1.1.2 - 03/12/2014 +Fixed CIE2000 calculations</releaseNotes> + <copyright>2014</copyright> + <language /> + <tags>color delta-e rgb to lab</tags> + </metadata> + <files> + <file src="bin\Release\ColorMine.dll" target="lib\ColorMine.dll" /> + </files> +</package>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpace.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpace.cs new file mode 100644 index 000000000..d67309e63 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpace.cs @@ -0,0 +1,83 @@ +using ColorMine.ColorSpaces.Comparisons; + +namespace ColorMine.ColorSpaces +{ + public delegate double ComparisonAlgorithm(IColorSpace a, IColorSpace b); + + /// <summary> + /// Defines the public methods for all color spaces + /// </summary> + public interface IColorSpace + { + /// <summary> + /// Initialize settings from an Rgb object + /// </summary> + /// <param name="color"></param> + void Initialize(IRgb color); + + /// <summary> + /// Convert the color space to Rgb, you should probably using the "To" method instead. Need to figure out a way to "hide" or otherwise remove this method from the public interface. + /// </summary> + /// <returns></returns> + IRgb ToRgb(); + + /// <summary> + /// Convert any IColorSpace to any other IColorSpace. + /// </summary> + /// <typeparam name="T">IColorSpace type to convert to</typeparam> + /// <returns></returns> + T To<T>() where T : IColorSpace, new(); + + /// <summary> + /// Determine how close two IColorSpaces are to each other using a passed in algorithm + /// </summary> + /// <param name="compareToValue">Other IColorSpace to compare to</param> + /// <param name="comparer">Algorithm to use for comparison</param> + /// <returns>Distance in 3d space as double</returns> + double Compare(IColorSpace compareToValue, IColorSpaceComparison comparer); + + /// <summary> + /// Array of signifigant values in a consistent order. Useful for generic n-dimensional math. + /// </summary> + double[] Ordinals { get; set; } + } + + /// <summary> + /// Abstract ColorSpace class, defines the To method that converts between any IColorSpace. + /// </summary> + public abstract class ColorSpace : IColorSpace + { + public abstract void Initialize(IRgb color); + public abstract IRgb ToRgb(); + public abstract double[] Ordinals { get; set; } + + /// <summary> + /// Convienience method for comparing any IColorSpace + /// </summary> + /// <param name="compareToValue"></param> + /// <param name="comparer"></param> + /// <returns>Single number representing the difference between two colors</returns> + public double Compare(IColorSpace compareToValue, IColorSpaceComparison comparer) + { + return comparer.Compare(this, compareToValue); + } + + /// <summary> + /// Convert any IColorSpace to any other IColorSpace + /// </summary> + /// <typeparam name="T">Must implement IColorSpace, new()</typeparam> + /// <returns></returns> + public T To<T>() where T : IColorSpace, new() + { + if (typeof(T) == GetType()) + { + return (T)MemberwiseClone(); + } + + var newColorSpace = new T(); + newColorSpace.Initialize(ToRgb()); + + return newColorSpace; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.cs new file mode 100644 index 000000000..4344113de --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.cs @@ -0,0 +1,791 @@ +// Note: This is a generated file. +using ColorMine.ColorSpaces.Conversions; + +namespace ColorMine.ColorSpaces +{ + public interface IRgb : IColorSpace + { + double R { get; set; } + double G { get; set; } + double B { get; set; } + } + + public class Rgb : ColorSpace, IRgb + { + public double R { get; set; } + public double G { get; set; } + public double B { get; set; } + + public Rgb() { } + + public Rgb(double r, double g, double b) + { + R = r; + G = g; + B = b; + } + + public Rgb(IColorSpace color) + { + Ordinals = color.To<Rgb>().Ordinals; + } + + public Rgb(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + RgbConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "R: " + R, + "G: " + G, + "B: " + B, + }); + } + + public override IRgb ToRgb() + { + return RgbConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { R, G, B, }; + } + set + { + R = value[0]; + G = value[1]; + B = value[2]; + } + } + } + public interface IXyz : IColorSpace + { + double X { get; set; } + double Y { get; set; } + double Z { get; set; } + } + + public class Xyz : ColorSpace, IXyz + { + public double X { get; set; } + public double Y { get; set; } + public double Z { get; set; } + + public Xyz() { } + + public Xyz(double x, double y, double z) + { + X = x; + Y = y; + Z = z; + } + + public Xyz(IColorSpace color) + { + Ordinals = color.To<Xyz>().Ordinals; + } + + public Xyz(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + XyzConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "X: " + X, + "Y: " + Y, + "Z: " + Z, + }); + } + + public override IRgb ToRgb() + { + return XyzConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { X, Y, Z, }; + } + set + { + X = value[0]; + Y = value[1]; + Z = value[2]; + } + } + } + public interface IHsl : IColorSpace + { + double H { get; set; } + double S { get; set; } + double L { get; set; } + } + + public class Hsl : ColorSpace, IHsl + { + public double H { get; set; } + public double S { get; set; } + public double L { get; set; } + + public Hsl() { } + + public Hsl(double h, double s, double l) + { + H = h; + S = s; + L = l; + } + + public Hsl(IColorSpace color) + { + Ordinals = color.To<Hsl>().Ordinals; + } + + public Hsl(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + HslConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "H: " + H, + "S: " + S, + "L: " + L, + }); + } + + public override IRgb ToRgb() + { + return HslConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { H, S, L, }; + } + set + { + H = value[0]; + S = value[1]; + L = value[2]; + } + } + } + public interface ILab : IColorSpace + { + double L { get; set; } + double A { get; set; } + double B { get; set; } + } + + public class Lab : ColorSpace, ILab + { + public double L { get; set; } + public double A { get; set; } + public double B { get; set; } + + public Lab() { } + + public Lab(double l, double a, double b) + { + L = l; + A = a; + B = b; + } + + public Lab(IColorSpace color) + { + Ordinals = color.To<Lab>().Ordinals; + } + + public Lab(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + LabConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "L: " + L, + "A: " + A, + "B: " + B, + }); + } + + public override IRgb ToRgb() + { + return LabConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { L, A, B, }; + } + set + { + L = value[0]; + A = value[1]; + B = value[2]; + } + } + } + public interface ILch : IColorSpace + { + double L { get; set; } + double C { get; set; } + double H { get; set; } + } + + public class Lch : ColorSpace, ILch + { + public double L { get; set; } + public double C { get; set; } + public double H { get; set; } + + public Lch() { } + + public Lch(double l, double c, double h) + { + L = l; + C = c; + H = h; + } + + public Lch(IColorSpace color) + { + Ordinals = color.To<Lch>().Ordinals; + } + + public Lch(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + LchConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "L: " + L, + "C: " + C, + "H: " + H, + }); + } + + public override IRgb ToRgb() + { + return LchConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { L, C, H, }; + } + set + { + L = value[0]; + C = value[1]; + H = value[2]; + } + } + } + public interface ILuv : IColorSpace + { + double L { get; set; } + double U { get; set; } + double V { get; set; } + } + + public class Luv : ColorSpace, ILuv + { + public double L { get; set; } + public double U { get; set; } + public double V { get; set; } + + public Luv() { } + + public Luv(double l, double u, double v) + { + L = l; + U = u; + V = v; + } + + public Luv(IColorSpace color) + { + Ordinals = color.To<Luv>().Ordinals; + } + + public Luv(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + LuvConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "L: " + L, + "U: " + U, + "V: " + V, + }); + } + + public override IRgb ToRgb() + { + return LuvConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { L, U, V, }; + } + set + { + L = value[0]; + U = value[1]; + V = value[2]; + } + } + } + public interface IYxy : IColorSpace + { + double Y1 { get; set; } + double X { get; set; } + double Y2 { get; set; } + } + + public class Yxy : ColorSpace, IYxy + { + public double Y1 { get; set; } + public double X { get; set; } + public double Y2 { get; set; } + + public Yxy() { } + + public Yxy(double y1, double x, double y2) + { + Y1 = y1; + X = x; + Y2 = y2; + } + + public Yxy(IColorSpace color) + { + Ordinals = color.To<Yxy>().Ordinals; + } + + public Yxy(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + YxyConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "Y1: " + Y1, + "X: " + X, + "Y2: " + Y2, + }); + } + + public override IRgb ToRgb() + { + return YxyConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { Y1, X, Y2, }; + } + set + { + Y1 = value[0]; + X = value[1]; + Y2 = value[2]; + } + } + } + public interface ICmy : IColorSpace + { + double C { get; set; } + double M { get; set; } + double Y { get; set; } + } + + public class Cmy : ColorSpace, ICmy + { + public double C { get; set; } + public double M { get; set; } + public double Y { get; set; } + + public Cmy() { } + + public Cmy(double c, double m, double y) + { + C = c; + M = m; + Y = y; + } + + public Cmy(IColorSpace color) + { + Ordinals = color.To<Cmy>().Ordinals; + } + + public Cmy(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + CmyConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "C: " + C, + "M: " + M, + "Y: " + Y, + }); + } + + public override IRgb ToRgb() + { + return CmyConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { C, M, Y, }; + } + set + { + C = value[0]; + M = value[1]; + Y = value[2]; + } + } + } + public interface ICmyk : IColorSpace + { + double C { get; set; } + double M { get; set; } + double Y { get; set; } + double K { get; set; } + } + + public class Cmyk : ColorSpace, ICmyk + { + public double C { get; set; } + public double M { get; set; } + public double Y { get; set; } + public double K { get; set; } + + public Cmyk() { } + + public Cmyk(double c, double m, double y, double k) + { + C = c; + M = m; + Y = y; + K = k; + } + + public Cmyk(IColorSpace color) + { + Ordinals = color.To<Cmyk>().Ordinals; + } + + public Cmyk(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + CmykConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "C: " + C, + "M: " + M, + "Y: " + Y, + "K: " + K, + }); + } + + public override IRgb ToRgb() + { + return CmykConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { C, M, Y, K, }; + } + set + { + C = value[0]; + M = value[1]; + Y = value[2]; + K = value[3]; + } + } + } + public interface IHsv : IColorSpace + { + double H { get; set; } + double S { get; set; } + double V { get; set; } + } + + public class Hsv : ColorSpace, IHsv + { + public double H { get; set; } + public double S { get; set; } + public double V { get; set; } + + public Hsv() { } + + public Hsv(double h, double s, double v) + { + H = h; + S = s; + V = v; + } + + public Hsv(IColorSpace color) + { + Ordinals = color.To<Hsv>().Ordinals; + } + + public Hsv(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + HsvConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "H: " + H, + "S: " + S, + "V: " + V, + }); + } + + public override IRgb ToRgb() + { + return HsvConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { H, S, V, }; + } + set + { + H = value[0]; + S = value[1]; + V = value[2]; + } + } + } + public interface IHsb : IColorSpace + { + double H { get; set; } + double S { get; set; } + double B { get; set; } + } + + public class Hsb : ColorSpace, IHsb + { + public double H { get; set; } + public double S { get; set; } + public double B { get; set; } + + public Hsb() { } + + public Hsb(double h, double s, double b) + { + H = h; + S = s; + B = b; + } + + public Hsb(IColorSpace color) + { + Ordinals = color.To<Hsb>().Ordinals; + } + + public Hsb(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + HsbConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "H: " + H, + "S: " + S, + "B: " + B, + }); + } + + public override IRgb ToRgb() + { + return HsbConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { H, S, B, }; + } + set + { + H = value[0]; + S = value[1]; + B = value[2]; + } + } + } + public interface IHunterLab : IColorSpace + { + double L { get; set; } + double A { get; set; } + double B { get; set; } + } + + public class HunterLab : ColorSpace, IHunterLab + { + public double L { get; set; } + public double A { get; set; } + public double B { get; set; } + + public HunterLab() { } + + public HunterLab(double l, double a, double b) + { + L = l; + A = a; + B = b; + } + + public HunterLab(IColorSpace color) + { + Ordinals = color.To<HunterLab>().Ordinals; + } + + public HunterLab(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + HunterLabConverter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ + "L: " + L, + "A: " + A, + "B: " + B, + }); + } + + public override IRgb ToRgb() + { + return HunterLabConverter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] { L, A, B, }; + } + set + { + L = value[0]; + A = value[1]; + B = value[2]; + } + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.tt b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.tt new file mode 100644 index 000000000..42581f739 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.tt @@ -0,0 +1,89 @@ +<#@ template debug="true" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Xml.dll" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import Namespace="System.Xml" #> +<#@ import Namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<# + var document = new XmlDocument(); + var file = Host.ResolvePath("ColorSpaces.xml"); + document.Load(file); + var colorSpaces = document.SelectNodes("colorSpaces/colorSpace"); +#> +<#@ output extension=".cs" #>// Note: This is a generated file. +using ColorMine.ColorSpaces.Conversions; + +namespace ColorMine.ColorSpaces +{ +<# foreach (XmlNode space in colorSpaces) { +var spaceName = space.Attributes["name"].Value; +var points = space.SelectNodes("dataPoints/dataPoint");#> + public interface I<#=spaceName#> : IColorSpace + { +<# foreach(XmlNode point in points) { #> + double <#=point.Attributes["label"].Value#> { get; set; } +<# } #> + } + + public class <#=spaceName#> : ColorSpace, I<#=spaceName#> + { +<# foreach(XmlNode point in points) { #> + public double <#=point.Attributes["label"].Value#> { get; set; } +<# } #> + + public <#=spaceName#>() { } + + public <#=spaceName#>(<# foreach(XmlNode point in points) { #>double <#=point.Attributes["label"].Value.ToLower()#><# if(point.Attributes != points[points.Count - 1].Attributes) { #>, <# } #><# } #>) + { +<# foreach(XmlNode point in points) { #> + <#=point.Attributes["label"].Value#> = <#=point.Attributes["label"].Value.ToLower()#>; +<# } #> + } + + public <#=spaceName#>(IColorSpace color) + { + Ordinals = color.To<<#=spaceName#>>().Ordinals; + } + + public <#=spaceName#>(double[] ordinals) + { + Ordinals = ordinals; + } + + public override void Initialize(IRgb color) + { + <#=spaceName#>Converter.ToColorSpace(color,this); + } + + public override string ToString() + { + return string.Join(", ", new []{ +<# foreach(XmlNode point in points) { #> + "<#=point.Attributes["label"].Value#>: " + <#=point.Attributes["label"].Value#>, +<# } #> + }); + } + + public override IRgb ToRgb() + { + return <#=spaceName#>Converter.ToColor(this); + } + + public override sealed double[] Ordinals + { + get + { + return new[] {<# foreach(XmlNode point in points) { #> <#=point.Attributes["label"].Value#>,<# } #> }; + } + set + { +<# var counter = 0; + foreach(XmlNode point in points) { #> + <#=point.Attributes["label"].Value#> = value[<#=counter++#>]; +<# } #> + } + } + } +<# } #>}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.xml b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.xml new file mode 100644 index 000000000..20e675bf3 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/ColorSpaces.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8" ?> +<colorSpaces> + <colorSpace name="Rgb"> + <dataPoints> + <dataPoint label="R" description="Red" min="0" max="255" /> + <dataPoint label="G" description="Green" min="0" max="255" /> + <dataPoint label="B" description="Blue" min="0" max="255" /> + </dataPoints> + </colorSpace> + <colorSpace name="Xyz"> + <dataPoints> + <dataPoint label="X" min="0" max="100"/> + <dataPoint label="Y" min="0" max="100"/> + <dataPoint label="Z" min="0" max="100"/> + </dataPoints> + </colorSpace> + <colorSpace name="Hsl"> + <dataPoints> + <dataPoint label="H" min="0" max="360"/> + <dataPoint label="S" min="0" max="100"/> + <dataPoint label="L" min="0" max="100"/> + </dataPoints> + </colorSpace> + <colorSpace name="Lab" description="CIE-L*ab"> + <dataPoints> + <dataPoint label="L" min="0" max="100"/> + <dataPoint label="A" min="-128" max="128"/> + <dataPoint label="B" min="-128" max="128"/> + </dataPoints> + </colorSpace> + <colorSpace name="Lch" description="CIE-Lch"> + <dataPoints> + <dataPoint label="L" min="0" max="100"/> + <dataPoint label="C" min="0" max="100"/> + <dataPoint label="H" min="0" max="360"/> + </dataPoints> + </colorSpace> + <colorSpace name="Luv" description="CIE-Luv"> + <dataPoints> + <dataPoint label="L" min="0" max="100"/> + <dataPoint label="U" min="-134" max="224"/> + <dataPoint label="V" min="-140" max ="122"/> + </dataPoints> + </colorSpace> + <colorSpace name="Yxy"> + <dataPoints> + <dataPoint label="Y1" min="0" max="100"/> + <dataPoint label="X" min="0" max="1"/> + <dataPoint label="Y2" min="0" max="1"/> + </dataPoints> + </colorSpace> + <colorSpace name="Cmy"> + <dataPoints> + <dataPoint label="C" min="0" max="1"/> + <dataPoint label="M" min="0" max="1"/> + <dataPoint label="Y" min="0" max="1"/> + </dataPoints> + </colorSpace> + <colorSpace name="Cmyk"> + <dataPoints> + <dataPoint label="C" min="0" max="1"/> + <dataPoint label="M" min="0" max="1"/> + <dataPoint label="Y" min="0" max="1"/> + <dataPoint label="K" min="0" max="1"/> + </dataPoints> + </colorSpace> + <colorSpace name="Hsv"> + <dataPoints> + <dataPoint label="H" min="0" max="360"/> + <dataPoint label="S" min="0" max="1"/> + <dataPoint label="V" min="0" max="1"/> + </dataPoints> + </colorSpace> + <colorSpace name="Hsb"> + <dataPoints> + <dataPoint label="H" min="0" max="360"/> + <dataPoint label="S" min="0" max="1"/> + <dataPoint label="B" min="0" max="1"/> + </dataPoints> + </colorSpace> + <colorSpace name="HunterLab"> + <dataPoints> + <dataPoint label="L" min="0" max="100"/> + <dataPoint label="A" min="-128" max="128"/> + <dataPoint label="B" min="-128" max="128"/> + </dataPoints> + </colorSpace> +</colorSpaces>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie1976Comparison.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie1976Comparison.cs new file mode 100644 index 000000000..276605fca --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie1976Comparison.cs @@ -0,0 +1,27 @@ +using System; + +namespace ColorMine.ColorSpaces.Comparisons +{ + /// <summary> + /// Implements the CIE76 method of delta-e: http://en.wikipedia.org/wiki/Color_difference#CIE76 + /// </summary> + public class Cie1976Comparison : IColorSpaceComparison + { + /// <summary> + /// Calculates the CIE76 delta-e value: http://en.wikipedia.org/wiki/Color_difference#CIE76 + /// </summary> + public double Compare(IColorSpace colorA, IColorSpace colorB) + { + var a = colorA.To<Lab>(); + var b = colorB.To<Lab>(); + + var differences = Distance(a.L, b.L) + Distance(a.A, b.A) + Distance(a.B, b.B); + return Math.Sqrt(differences); + } + + private static double Distance(double a, double b) + { + return (a - b) * (a - b); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie94Comparison.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie94Comparison.cs new file mode 100644 index 000000000..a2585b688 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/Cie94Comparison.cs @@ -0,0 +1,99 @@ +using System; + +namespace ColorMine.ColorSpaces.Comparisons +{ + /// <summary> + /// Implements the Cie94 method of delta-e: http://en.wikipedia.org/wiki/Color_difference#CIE94 + /// </summary> + public class Cie94Comparison : IColorSpaceComparison + { + /// <summary> + /// Application type defines constants used in the Cie94 comparison + /// </summary> + public enum Application + { + GraphicArts, + Textiles + } + + + internal ApplicationConstants Constants { get; private set; } + + /// <summary> + /// Create new Cie94Comparison. Defaults to GraphicArts application type. + /// </summary> + public Cie94Comparison() + { + Constants = new ApplicationConstants(Application.GraphicArts); + } + + /// <summary> + /// Create new Cie94Comparison for specific application type. + /// </summary> + /// <param name="application"></param> + public Cie94Comparison(Application application) + { + Constants = new ApplicationConstants(application); + } + + /// <summary> + /// Compare colors using the Cie94 algorithm. The first color (a) will be used as the reference color. + /// </summary> + /// <param name="a">Reference color</param> + /// <param name="b">Comparison color</param> + /// <returns></returns> + public double Compare(IColorSpace a, IColorSpace b) + { + var labA = a.To<Lab>(); + var labB = b.To<Lab>(); + + var deltaL = labA.L - labB.L; + var deltaA = labA.A - labB.A; + var deltaB = labA.B - labB.B; + + var c1 = Math.Sqrt(labA.A * labA.A + labA.B * labA.B); + var c2 = Math.Sqrt(labB.A * labB.A + labB.B * labB.B); + var deltaC = c1 - c2; + + var deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC; + deltaH = deltaH < 0 ? 0 : Math.Sqrt(deltaH); + + const double sl = 1.0; + const double kc = 1.0; + const double kh = 1.0; + + var sc = 1.0 + Constants.K1 * c1; + var sh = 1.0 + Constants.K2 * c1; + + var deltaLKlsl = deltaL / (Constants.Kl * sl); + var deltaCkcsc = deltaC / (kc * sc); + var deltaHkhsh = deltaH / (kh * sh); + var i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh; + return i < 0 ? 0 : Math.Sqrt(i); + } + + internal class ApplicationConstants + { + internal double Kl { get; private set; } + internal double K1 { get; private set; } + internal double K2 { get; private set; } + + public ApplicationConstants(Application application) + { + switch (application) + { + case Application.GraphicArts: + Kl = 1.0; + K1 = .045; + K2 = .015; + break; + case Application.Textiles: + Kl = 2.0; + K1 = .048; + K2 = .014; + break; + } + } + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CieDe2000Comparison.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CieDe2000Comparison.cs new file mode 100644 index 000000000..f47ad6917 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CieDe2000Comparison.cs @@ -0,0 +1,127 @@ +using ColorMine.ColorSpaces.Utility; +using System; + +namespace ColorMine.ColorSpaces.Comparisons +{ + /// <summary> + /// Implements the DE2000 method of delta-e: http://en.wikipedia.org/wiki/Color_difference#CIEDE2000 + /// Correct implementation provided courtesy of Jonathan Hofinger, jaytar42 + /// </summary> + public class CieDe2000Comparison : IColorSpaceComparison + { + /// <summary> + /// Calculates the DE2000 delta-e value: http://en.wikipedia.org/wiki/Color_difference#CIEDE2000 + /// Correct implementation provided courtesy of Jonathan Hofinger, jaytar42 + /// </summary> + public double Compare(IColorSpace c1, IColorSpace c2) + { + //Set weighting factors to 1 + double k_L = 1.0d; + double k_C = 1.0d; + double k_H = 1.0d; + + + //Change Color Space to L*a*b: + Lab lab1 = c1.To<Lab>(); + Lab lab2 = c2.To<Lab>(); + + //Calculate Cprime1, Cprime2, Cabbar + double c_star_1_ab = Math.Sqrt(lab1.A * lab1.A + lab1.B * lab1.B); + double c_star_2_ab = Math.Sqrt(lab2.A * lab2.A + lab2.B * lab2.B); + double c_star_average_ab = (c_star_1_ab + c_star_2_ab) / 2; + + double c_star_average_ab_pot7 = c_star_average_ab * c_star_average_ab * c_star_average_ab; + c_star_average_ab_pot7 *= c_star_average_ab_pot7 * c_star_average_ab; + + double G = 0.5d * (1 - Math.Sqrt(c_star_average_ab_pot7 / (c_star_average_ab_pot7 + 6103515625))); //25^7 + double a1_prime = (1 + G) * lab1.A; + double a2_prime = (1 + G) * lab2.A; + + double C_prime_1 = Math.Sqrt(a1_prime * a1_prime + lab1.B * lab1.B); + double C_prime_2 = Math.Sqrt(a2_prime * a2_prime + lab2.B * lab2.B); + //Angles in Degree. + double h_prime_1 = (MathUtils.RadToDeg(Math.Atan2(lab1.B, a1_prime)) + 360) % 360d; + double h_prime_2 = (MathUtils.RadToDeg(Math.Atan2(lab2.B, a2_prime)) + 360) % 360d; + + double delta_L_prime = lab2.L - lab1.L; + double delta_C_prime = C_prime_2 - C_prime_1; + + double h_bar = Math.Abs(h_prime_1 - h_prime_2); + double delta_h_prime; + if (C_prime_1 * C_prime_2 == 0) delta_h_prime = 0; + else + { + if (h_bar <= 180d) + { + delta_h_prime = h_prime_2 - h_prime_1; + } + else if (h_bar > 180d && h_prime_2 <= h_prime_1) + { + delta_h_prime = h_prime_2 - h_prime_1 + 360.0; + } + else + { + delta_h_prime = h_prime_2 - h_prime_1 - 360.0; + } + } + double delta_H_prime = 2 * Math.Sqrt(C_prime_1 * C_prime_2) * Math.Sin(MathUtils.DegToRad(delta_h_prime / 2)); + + // Calculate CIEDE2000 + double L_prime_average = (lab1.L + lab2.L) / 2d; + double C_prime_average = (C_prime_1 + C_prime_2) / 2d; + + //Calculate h_prime_average + + double h_prime_average; + if (C_prime_1 * C_prime_2 == 0) h_prime_average = 0; + else + { + if (h_bar <= 180d) + { + h_prime_average = (h_prime_1 + h_prime_2) / 2; + } + else if (h_bar > 180d && (h_prime_1 + h_prime_2) < 360d) + { + h_prime_average = (h_prime_1 + h_prime_2 + 360d) / 2; + } + else + { + h_prime_average = (h_prime_1 + h_prime_2 - 360d) / 2; + } + } + double L_prime_average_minus_50_square = (L_prime_average - 50); + L_prime_average_minus_50_square *= L_prime_average_minus_50_square; + + double S_L = 1 + ((.015d * L_prime_average_minus_50_square) / Math.Sqrt(20 + L_prime_average_minus_50_square)); + double S_C = 1 + .045d * C_prime_average; + double T = 1 + - .17 * Math.Cos(MathUtils.DegToRad(h_prime_average - 30)) + + .24 * Math.Cos(MathUtils.DegToRad(h_prime_average * 2)) + + .32 * Math.Cos(MathUtils.DegToRad(h_prime_average * 3 + 6)) + - .2 * Math.Cos(MathUtils.DegToRad(h_prime_average * 4 - 63)); + double S_H = 1 + .015 * T * C_prime_average; + double h_prime_average_minus_275_div_25_square = (h_prime_average - 275) / (25); + h_prime_average_minus_275_div_25_square *= h_prime_average_minus_275_div_25_square; + double delta_theta = 30 * Math.Exp(-h_prime_average_minus_275_div_25_square); + + double C_prime_average_pot_7 = C_prime_average * C_prime_average * C_prime_average; + C_prime_average_pot_7 *= C_prime_average_pot_7 * C_prime_average; + double R_C = 2 * Math.Sqrt(C_prime_average_pot_7 / (C_prime_average_pot_7 + 6103515625)); + + double R_T = -Math.Sin(MathUtils.DegToRad(2 * delta_theta)) * R_C; + + double delta_L_prime_div_k_L_S_L = delta_L_prime / (S_L * k_L); + double delta_C_prime_div_k_C_S_C = delta_C_prime / (S_C * k_C); + double delta_H_prime_div_k_H_S_H = delta_H_prime / (S_H * k_H); + + double CIEDE2000 = Math.Sqrt( + delta_L_prime_div_k_L_S_L * delta_L_prime_div_k_L_S_L + + delta_C_prime_div_k_C_S_C * delta_C_prime_div_k_C_S_C + + delta_H_prime_div_k_H_S_H * delta_H_prime_div_k_H_S_H + + R_T * delta_C_prime_div_k_C_S_C * delta_H_prime_div_k_H_S_H + ); + + return CIEDE2000; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CmcComparison.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CmcComparison.cs new file mode 100644 index 000000000..34a06da24 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/CmcComparison.cs @@ -0,0 +1,84 @@ +using ColorMine.ColorSpaces.Utility; +using System; + +namespace ColorMine.ColorSpaces.Comparisons +{ + /// <summary> + /// Implements the CMC l:c (1984) method of delta-e: http://en.wikipedia.org/wiki/Color_difference#CMC_l:c_.281984.29 + /// </summary> + public class CmcComparison : IColorSpaceComparison + { + public const double DefaultLightness = 2.0; + public const double DefaultChroma = 1.0; + + private readonly double _lightness; + private readonly double _chroma; + + /// <summary> + /// Create CMC l:c comparison with DefaultLightness and DefaultChroma values. + /// </summary> + public CmcComparison() + { + _lightness = DefaultLightness; + _chroma = DefaultChroma; + } + + /// <summary> + /// Create CMC l:c comparison with specific lightness (l) and chroma (c) values. + /// </summary> + /// <param name="lightness"></param> + /// <param name="chroma"></param> + public CmcComparison(double lightness = DefaultLightness, double chroma = DefaultChroma) + { + _lightness = lightness; + _chroma = chroma; + } + + /// <summary> + /// Calculates the CMC l:c (1984) delta-e value: http://en.wikipedia.org/wiki/Color_difference#CMC_l:c_.281984.29 + /// </summary> + /// <param name="colorA"></param> + /// <param name="colorB"></param> + /// <returns></returns> + public double Compare(IColorSpace colorA, IColorSpace colorB) + { + var aLab = colorA.To<Lab>(); + var bLab = colorB.To<Lab>(); + + var deltaL = aLab.L - bLab.L; + var h = MathUtils.RadToDeg(Math.Atan2(aLab.B, aLab.A)); + + var c1 = Math.Sqrt(aLab.A * aLab.A + aLab.B * aLab.B); + var c2 = Math.Sqrt(bLab.A * bLab.A + bLab.B * bLab.B); + var deltaC = c1 - c2; + + var deltaH_2 = + (aLab.A - bLab.A) * (aLab.A - bLab.A) + + (aLab.B - bLab.B) * (aLab.B - bLab.B) - + deltaC * deltaC; + + var c1_4 = c1 * c1; + c1_4 *= c1_4; + var t = 164 <= h && h <= 345 + ? .56 + Math.Abs(.2 * Math.Cos(MathUtils.DegToRad(h + 168.0))) + : .36 + Math.Abs(.4 * Math.Cos(MathUtils.DegToRad(h + 35.0))); + var f = Math.Sqrt(c1_4 / (c1_4 + 1900.0)); + + var sL = aLab.L < 16 ? .511 : (.040975 * aLab.L) / (1.0 + .01765 * aLab.L); + var sC = (.0638 * c1) / (1 + .0131 * c1) + .638; + var sH = sC * (f * t + 1 - f); + + var differences = DistanceDivided(deltaL, _lightness * sL) + + DistanceDivided(deltaC, _chroma * sC) + + deltaH_2 / (sH * sH); + + return Math.Sqrt(differences); + } + + private static double DistanceDivided(double a, double dividend) + { + var adiv = a / dividend; + return adiv * adiv; + } + } +} diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/IColorSpaceComparison.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/IColorSpaceComparison.cs new file mode 100644 index 000000000..c6a789e62 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Comparisons/IColorSpaceComparison.cs @@ -0,0 +1,16 @@ +namespace ColorMine.ColorSpaces.Comparisons +{ + /// <summary> + /// Defines how comparison methods may be called + /// </summary> + public interface IColorSpaceComparison + { + /// <summary> + /// Returns the difference between two colors given based on the specified defined in the called class. + /// </summary> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>Score based on similarity, the lower the score the closer the colors</returns> + double Compare(IColorSpace a, IColorSpace b); + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmyConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmyConverter.cs new file mode 100644 index 000000000..9851d809a --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmyConverter.cs @@ -0,0 +1,22 @@ +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class CmyConverter + { + internal static void ToColorSpace(IRgb color, ICmy item) + { + item.C = 1 - color.R / 255.0; + item.M = 1 - color.G / 255.0; + item.Y = 1 - color.B / 255.0; + } + + internal static IRgb ToColor(ICmy item) + { + return new Rgb + { + R = (1 - item.C) * 255.0, + G = (1 - item.M) * 255.0, + B = (1 - item.Y) * 255.0 + }; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmykConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmykConverter.cs new file mode 100644 index 000000000..cd5a33eb5 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/CmykConverter.cs @@ -0,0 +1,47 @@ +using ColorMine.ColorSpaces.Utility; + +namespace ColorMine.ColorSpaces.Conversions +{ + public static class CmykConverter + { + public static void ToColorSpace(IRgb color, ICmyk item) + { + var cmy = new Cmy(); + cmy.Initialize(color); + + var k = 1.0; + if (cmy.C < k) + k = cmy.C; + if (cmy.M < k) + k = cmy.M; + if (cmy.Y < k) + k = cmy.Y; + item.K = k; + + if (k.BasicallyEqualTo(1)) + { + item.C = 0; + item.M = 0; + item.Y = 0; + } + else + { + item.C = (cmy.C - k) / (1 - k); + item.M = (cmy.M - k) / (1 - k); + item.Y = (cmy.Y - k) / (1 - k); + } + } + + public static IRgb ToColor(ICmyk item) + { + var cmy = new Cmy + { + C = (item.C * (1 - item.K) + item.K), + M = (item.M * (1 - item.K) + item.K), + Y = (item.Y * (1 - item.K) + item.K) + }; + + return cmy.ToRgb(); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsbConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsbConverter.cs new file mode 100644 index 000000000..f3705fdd5 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsbConverter.cs @@ -0,0 +1,29 @@ +namespace ColorMine.ColorSpaces.Conversions +{ + /// <summary> + /// HSB is another name for HSV + /// </summary> + internal static class HsbConverter + { + internal static void ToColorSpace(IRgb color, IHsb item) + { + var hsv = new Hsv(); + HsvConverter.ToColorSpace(color, hsv); + + item.H = hsv.H; + item.S = hsv.S; + item.B = hsv.V; + } + + internal static IRgb ToColor(IHsb item) + { + var hsv = new Hsv + { + H = item.H, + S = item.S, + V = item.B + }; + return HsvConverter.ToColor(hsv); + } + } +} diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HslConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HslConverter.cs new file mode 100644 index 000000000..4be751723 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HslConverter.cs @@ -0,0 +1,149 @@ +using static System.Math; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class HslConverter + { + public static IHsl ToColorSpace(double R, double G, double B) + { + var min = Min(R, Min(G, B)); //Min. value of RGB + var max = Max(R, Max(G, B)); //Max. value of RGB + var chroma = max - min; + + double H = 0, S = 0, L = 0; + L = (max + min) / 2; + + if (chroma == 0) // This is a gray, no chroma... + { + H = 0; + S = 0; + } + else + { + if (L <= 0.5) + { + S = chroma / (2 * L); //max / (max + min); + } + else + { + S = chroma / (2 - 2 * L); // max / (2 - max - min); + } + + if (R == max) + { + H = (G - B) / chroma; + if (G < B) + { + H += 6; + } + } + else if (B == max) + { + H = 4 + ((R - G) / chroma); + } + else if (G == max) + { + H = 2 + ((B - R) / chroma); + } + + + H *= 60; + } + return new Hsl(H, S, L); + } + + internal static void ToColorSpace(IRgb color, IHsl item) + { + var result = ToColorSpace(color.R / 255d, color.G / 255d, color.B / 255d); + item.H = result.H; + item.S = result.S; + item.L = result.L; + + // Range expected by HSL is integer + item.S = Round(item.S * 100, 3); + item.L = Round(item.L * 100, 3); + } + + private static IRgb Rotate(double h, double s, ref double l) + { + // Avoid exactly zero hue, it does weird things + if(h==0) { h = 0.00001; } + var chroma = (1 - Abs(2 * l - 1)) * s; + var x = chroma * (1 - Abs((h % 2d) - 1)); + l -= 0.5 * chroma; + + switch (Ceiling(h)) + { + case 1d: + return new Rgb(chroma, x, 0); + case 2d: + return new Rgb(x, chroma, 0); + case 3d: + return new Rgb(0, chroma, x); + case 4d: + return new Rgb(0, x, chroma); + case 5d: + return new Rgb(x, 0, chroma); + case 6d: + return new Rgb(chroma, 0, x); + default: + return new Rgb(0, 0, 0); + } + } + + internal static IRgb ToColor(IHsl item) + { + var h = item.H / 60.0; + var s = item.S / 100.0; + var l = item.L / 100.0; + if (s > 0) + { + var result = Rotate(h, s, ref l); + + return new Rgb + { + R = (result.R + l) * 255, + G = (result.G + l) * 255, + B = (result.B + l) * 255 + }; + } + else + { + return new Rgb + { + R = l * 255, + G = l * 255, + B = l * 255 + }; + } + } + + private static double GetColorComponent(double temp1, double temp2, double temp3) + { + temp3 = MoveIntoRange(temp3); + if (temp3 < 1.0 / 6.0) + { + return temp1 + (temp2 - temp1) * 6.0 * temp3; + } + + if (temp3 < 0.5) + { + return temp2; + } + + if (temp3 < 2.0 / 3.0) + { + return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0); + } + + return temp1; + } + + private static double MoveIntoRange(double temp3) + { + if (temp3 < 0.0) return temp3 + 1.0; + if (temp3 > 1.0) return temp3 - 1.0; + return temp3; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsvConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsvConverter.cs new file mode 100644 index 000000000..c980a7739 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HsvConverter.cs @@ -0,0 +1,91 @@ +using System; +using static System.Math; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class HsvConverter + { + public static IHsv ToColorSpace(double R, double G, double B) + { + var min = Min(R, Min(G, B)); //Min. value of RGB + var max = Max(R, Max(G, B)); //Max. value of RGB + var chroma = max - min; + + double H = 0, S = 0, V = 0; + V = max; + + if (chroma == 0) // This is a gray, no chroma... + { + H = 0; + S = 0; + } + else + { + S = chroma / max; + + if (R == max) + { + H = (G - B) / chroma; + if (G < B) + { + H += 6; + } + } + else if (G == max) + { + H = 2 + ((B - R) / chroma); + } + else if (B == max) + { + H = 4 + ((R - G) / chroma); + } + + H *= 60; + } + return new Hsv(H, S, V); + } + + internal static void ToColorSpace(IRgb color, IHsv item) + { + var result = ToColorSpace(color.R / 255d, color.G / 255d, color.B / 255d); + item.H = result.H; + item.S = result.S; + item.V = result.V; + + //item.H = Color.FromArgb(255, (int)color.R, (int)color.G, (int)color.B).GetHue(); + //item.S = (max <= 0) ? 0 : 1d - (1d * min / max); + //item.V = max / 255d; + } + + internal static IRgb ToColor(IHsv item) + { + var range = Convert.ToInt32(Math.Floor(item.H / 60.0)) % 6; + var f = item.H / 60.0 - Math.Floor(item.H / 60.0); + + var v = item.V * 255.0; + var p = v * (1 - item.S); + var q = v * (1 - f * item.S); + var t = v * (1 - (1 - f) * item.S); + + switch (range) + { + case 0: + return NewRgb(v, t, p); + case 1: + return NewRgb(q, v, p); + case 2: + return NewRgb(p, v, t); + case 3: + return NewRgb(p, q, v); + case 4: + return NewRgb(t, p, v); + } + return NewRgb(v, p, q); + } + + private static IRgb NewRgb(double r, double g, double b) + { + return new Rgb { R = r, G = g, B = b }; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HunterLabConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HunterLabConverter.cs new file mode 100644 index 000000000..0e0b4f3bb --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/HunterLabConverter.cs @@ -0,0 +1,33 @@ +using System; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class HunterLabConverter + { + + internal static void ToColorSpace(IRgb color, IHunterLab item) + { + var xyz = color.To<Xyz>(); + + item.L = 10.0 * Math.Sqrt(xyz.Y); + item.A = xyz.Y != 0 ? 17.5 * (((1.02 * xyz.X) - xyz.Y) / Math.Sqrt(xyz.Y)) : 0; + item.B = xyz.Y != 0 ? 7.0 * ((xyz.Y - (.847 * xyz.Z)) / Math.Sqrt(xyz.Y)) : 0; + } + + internal static IRgb ToColor(IHunterLab item) + { + var x = (item.A / 17.5) * (item.L / 10.0); + var itemL_10 = item.L / 10.0; + var y = itemL_10 * itemL_10; + var z = item.B / 7.0 * item.L / 10.0; + + var xyz = new Xyz + { + X = (x + y) / 1.02, + Y = y, + Z = -(z - y) / .847 + }; + return xyz.To<Rgb>(); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LabConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LabConverter.cs new file mode 100644 index 000000000..57535b40c --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LabConverter.cs @@ -0,0 +1,51 @@ +using System; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class LabConverter + { + internal static void ToColorSpace(IRgb color, ILab item) + { + var xyz = new Xyz(); + xyz.Initialize(color); + + var white = XyzConverter.WhiteReference; + var x = PivotXyz(xyz.X / white.X); + var y = PivotXyz(xyz.Y / white.Y); + var z = PivotXyz(xyz.Z / white.Z); + + item.L = Math.Max(0, 116 * y - 16); + item.A = 500 * (x - y); + item.B = 200 * (y - z); + } + + internal static IRgb ToColor(ILab item) + { + var y = (item.L + 16.0) / 116.0; + var x = item.A / 500.0 + y; + var z = y - item.B / 200.0; + + var white = XyzConverter.WhiteReference; + var x3 = x * x * x; + var z3 = z * z * z; + var xyz = new Xyz + { + X = white.X * (x3 > XyzConverter.Epsilon ? x3 : (x - 16.0 / 116.0) / 7.787), + Y = white.Y * (item.L > (XyzConverter.Kappa * XyzConverter.Epsilon) ? Math.Pow(((item.L + 16.0) / 116.0), 3) : item.L / XyzConverter.Kappa), + Z = white.Z * (z3 > XyzConverter.Epsilon ? z3 : (z - 16.0 / 116.0) / 7.787) + }; + + return xyz.ToRgb(); + } + + private static double PivotXyz(double n) + { + return n > XyzConverter.Epsilon ? CubicRoot(n) : (XyzConverter.Kappa * n + 16) / 116; + } + + private static double CubicRoot(double n) + { + return Math.Pow(n, 1.0 / 3.0); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LchConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LchConverter.cs new file mode 100644 index 000000000..871777851 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LchConverter.cs @@ -0,0 +1,39 @@ +using ColorMine.ColorSpaces.Utility; +using System; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class LchConverter + { + internal static void ToColorSpace(IRgb color, ILch item) + { + var lab = color.To<Lab>(); + var h = MathUtils.RadToDeg(Math.Atan2(lab.B, lab.A)); + + if (h < 0) + { + h += 360.0; + } + else if (h >= 360) + { + h -= 360.0; + } + + item.L = lab.L; + item.C = Math.Sqrt(lab.A * lab.A + lab.B * lab.B); + item.H = h; + } + + internal static IRgb ToColor(ILch item) + { + var hRadians = MathUtils.DegToRad(item.H); + var lab = new Lab + { + L = item.L, + A = Math.Cos(hRadians) * item.C, + B = Math.Sin(hRadians) * item.C + }; + return lab.To<Rgb>(); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LuvConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LuvConverter.cs new file mode 100644 index 000000000..6b6d1f353 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/LuvConverter.cs @@ -0,0 +1,57 @@ +using System; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class LuvConverter + { + internal static void ToColorSpace(IRgb color, ILuv item) + { + var xyz = new Xyz(); + var white = XyzConverter.WhiteReference; + xyz.Initialize(color); + + var y = xyz.Y / XyzConverter.WhiteReference.Y; + item.L = y > XyzConverter.Epsilon ? 116.0 * XyzConverter.CubicRoot(y) - 16.0 : XyzConverter.Kappa * y; + + var targetDenominator = GetDenominator(xyz); + var referenceDenominator = GetDenominator(white); + // ReSharper disable CompareOfFloatsByEqualityOperator + var xTarget = targetDenominator == 0 ? 0 : ((4.0 * xyz.X / targetDenominator) - (4.0 * white.X / referenceDenominator)); + var yTarget = targetDenominator == 0 ? 0 : ((9.0 * xyz.Y / targetDenominator) - (9.0 * white.Y / referenceDenominator)); + // ReSharper restore CompareOfFloatsByEqualityOperator + + item.U = 13.0 * item.L * xTarget; + item.V = 13.0 * item.L * yTarget; + } + + internal static IRgb ToColor(ILuv item) + { + var white = XyzConverter.WhiteReference; + const double c = -1.0 / 3.0; + var uPrime = (4.0 * white.X) / GetDenominator(white); + var vPrime = (9.0 * white.Y) / GetDenominator(white); + var a = (1.0 / 3.0) * ((52.0 * item.L) / (item.U + 13 * item.L * uPrime) - 1.0); + var imteL_16_116 = (item.L + 16.0) / 116.0; + var y = item.L > XyzConverter.Kappa * XyzConverter.Epsilon + ? imteL_16_116 * imteL_16_116 * imteL_16_116 + : item.L / XyzConverter.Kappa; + var b = -5.0 * y; + var d = y * ((39.0 * item.L) / (item.V + 13.0 * item.L * vPrime) - 5.0); + var x = (d - b) / (a - c); + var z = x * a + b; + var xyz = new Xyz + { + X = 100 * x, + Y = 100 * y, + Z = 100 * z + }; + return xyz.ToRgb(); + + } + + private static double GetDenominator(IXyz xyz) + { + return xyz.X + 15.0 * xyz.Y + 3.0 * xyz.Z; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/RgbConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/RgbConverter.cs new file mode 100644 index 000000000..7774b977f --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/RgbConverter.cs @@ -0,0 +1,17 @@ +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class RgbConverter + { + internal static void ToColorSpace(IRgb color, IRgb item) + { + item.R = color.R; + item.G = color.G; + item.B = color.B; + } + + internal static IRgb ToColor(IRgb item) + { + return item; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/XyzConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/XyzConverter.cs new file mode 100644 index 000000000..bf4e187bb --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/XyzConverter.cs @@ -0,0 +1,75 @@ +using System; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class XyzConverter + { + #region Constants/Helper methods for Xyz related spaces + internal static IXyz WhiteReference { get; private set; } // TODO: Hard-coded! + internal const double Epsilon = 0.008856; // Intent is 216/24389 + internal const double Kappa = 903.3; // Intent is 24389/27 + static XyzConverter() + { + WhiteReference = new Xyz + { + X = 95.047, + Y = 100.000, + Z = 108.883 + }; + } + + internal static double CubicRoot(double n) + { + return Math.Pow(n, 1.0 / 3.0); + } + #endregion + + internal static void ToColorSpace(IRgb color, IXyz item) + { + var r = PivotRgb(color.R / 255.0); + var g = PivotRgb(color.G / 255.0); + var b = PivotRgb(color.B / 255.0); + + // Observer. = 2°, Illuminant = D65 + item.X = r * 0.4124 + g * 0.3576 + b * 0.1805; + item.Y = r * 0.2126 + g * 0.7152 + b * 0.0722; + item.Z = r * 0.0193 + g * 0.1192 + b * 0.9505; + } + + internal static IRgb ToColor(IXyz item) + { + // (Observer = 2°, Illuminant = D65) + var x = item.X / 100.0; + var y = item.Y / 100.0; + var z = item.Z / 100.0; + + var r = x * 3.2406 + y * -1.5372 + z * -0.4986; + var g = x * -0.9689 + y * 1.8758 + z * 0.0415; + var b = x * 0.0557 + y * -0.2040 + z * 1.0570; + + r = r > 0.0031308 ? 1.055 * Math.Pow(r, 1 / 2.4) - 0.055 : 12.92 * r; + g = g > 0.0031308 ? 1.055 * Math.Pow(g, 1 / 2.4) - 0.055 : 12.92 * g; + b = b > 0.0031308 ? 1.055 * Math.Pow(b, 1 / 2.4) - 0.055 : 12.92 * b; + + return new Rgb + { + R = ToRgb(r), + G = ToRgb(g), + B = ToRgb(b) + }; + } + + private static double ToRgb(double n) + { + var result = 255.0 * n; + if (result < 0) return 0; + if (result > 255) return 255; + return result; + } + + private static double PivotRgb(double n) + { + return (n > 0.04045 ? Math.Pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/YxyConverter.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/YxyConverter.cs new file mode 100644 index 000000000..51344e897 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Conversions/YxyConverter.cs @@ -0,0 +1,32 @@ +using ColorMine.ColorSpaces.Utility; + +namespace ColorMine.ColorSpaces.Conversions +{ + internal static class YxyConverter + { + internal static void ToColorSpace(IRgb color, IYxy item) + { + var xyz = new Xyz(); + xyz.Initialize(color); + + item.Y1 = xyz.Y; + + var xDividend = xyz.X + xyz.Y + xyz.Z; + item.X = xDividend.BasicallyEqualTo(0) ? 0.0 : xyz.X / xDividend; + + var y2Dividend = xyz.X + xyz.Y + xyz.Z; + item.Y2 = y2Dividend.BasicallyEqualTo(0) ? 0.0 : xyz.Y / (xyz.X + xyz.Y + xyz.Z); + } + + internal static IRgb ToColor(IYxy item) + { + var xyz = new Xyz + { + X = item.X * (item.Y1 / item.Y2), + Y = item.Y1, + Z = (1.0 - item.X - item.Y2) * (item.Y1 / item.Y2) + }; + return xyz.ToRgb(); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/DoubleExtension.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/DoubleExtension.cs new file mode 100644 index 000000000..cc9733ff7 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/DoubleExtension.cs @@ -0,0 +1,19 @@ +using System; + +namespace ColorMine.ColorSpaces.Utility +{ + internal static class DoubleExtension + { + private const double DefaultPrecision = .0001; + + internal static bool BasicallyEqualTo(this double a, double b) + { + return a.BasicallyEqualTo(b, DefaultPrecision); + } + + internal static bool BasicallyEqualTo(this double a, double b, double precision) + { + return Math.Abs(a - b) <= precision; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/MathUtils.cs b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/MathUtils.cs new file mode 100644 index 000000000..1aa9334d6 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/ColorSpaces/Utility/MathUtils.cs @@ -0,0 +1,17 @@ +using System; + +namespace ColorMine.ColorSpaces.Utility +{ + internal static class MathUtils + { + internal static double DegToRad(double degrees) + { + return degrees * Math.PI / 180; + } + + internal static double RadToDeg(double radians) + { + return radians / Math.PI * 180; + } + } +} diff --git a/Software/Visual_Studio/SideChains/ColorMine/Properties/AssemblyInfo.cs b/Software/Visual_Studio/SideChains/ColorMine/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9f0124f76 --- /dev/null +++ b/Software/Visual_Studio/SideChains/ColorMine/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ColorMine.Test")]
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.ColorPicker/ColorPicker/Themes/Generic.xaml b/Software/Visual_Studio/Tango.ColorPicker/ColorPicker/Themes/Generic.xaml index 996da3308..17d1dc967 100644 --- a/Software/Visual_Studio/Tango.ColorPicker/ColorPicker/Themes/Generic.xaml +++ b/Software/Visual_Studio/Tango.ColorPicker/ColorPicker/Themes/Generic.xaml @@ -219,7 +219,7 @@ <Setter.Value> <ControlTemplate TargetType="{x:Type local:ColorPickerCombo}"> <Grid> - <ToggleButton x:Name="PART_ColorPickerToggleButton" Style="{x:Null}" Background="#E9E9E9" + <ToggleButton x:Name="PART_ColorPickerToggleButton" Style="{x:Null}" Background="White" BorderBrush="#55B2EC" IsTabStop="True" MinHeight="22" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index a533cf1cd..3129ace25 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -117,6 +117,8 @@ Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Tango.MachineStudio.Install EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.SQLiteGenerator.CLI", "Utilities\Tango.SQLiteGenerator.CLI\Tango.SQLiteGenerator.CLI.csproj", "{8A03ADC0-991B-4DA8-8A19-E1D03F92E81C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorMine", "SideChains\ColorMine\ColorMine.csproj", "{37E4CEAB-B54B-451F-B535-04CF7DA9C459}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1496,6 +1498,36 @@ Global {8A03ADC0-991B-4DA8-8A19-E1D03F92E81C}.Release|x64.Build.0 = Release|Any CPU {8A03ADC0-991B-4DA8-8A19-E1D03F92E81C}.Release|x86.ActiveCfg = Release|Any CPU {8A03ADC0-991B-4DA8-8A19-E1D03F92E81C}.Release|x86.Build.0 = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|ARM.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|ARM.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|ARM64.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|x64.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|x64.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|x86.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Debug|x86.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|ARM.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|ARM.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|ARM64.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|ARM64.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|x64.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|x64.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|x86.ActiveCfg = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.DefaultBuild|x86.Build.0 = Debug|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|Any CPU.Build.0 = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|ARM.ActiveCfg = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|ARM.Build.0 = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|ARM64.ActiveCfg = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|ARM64.Build.0 = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|x64.ActiveCfg = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|x64.Build.0 = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|x86.ActiveCfg = Release|Any CPU + {37E4CEAB-B54B-451F-B535-04CF7DA9C459}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1528,5 +1560,6 @@ Global {B9AE25D6-BE35-492F-9079-21A7F3E6F7CC} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} {A19DEAB8-7356-4BCD-9FA8-B2FA09077165} = {57DF2A95-5DDD-4830-A4AF-B484B59C7C2B} {8A03ADC0-991B-4DA8-8A19-E1D03F92E81C} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} + {37E4CEAB-B54B-451F-B535-04CF7DA9C459} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} EndGlobalSection EndGlobal |
