diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0cb0e60
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+################################################################################
+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
+################################################################################
+
+/LegoArt/obj
+/LegoArt/bin/Debug/netcoreapp3.1
+/.vs/LegoArt/v16/TestStore/0
diff --git a/LegoArt.sln b/LegoArt.sln
new file mode 100644
index 0000000..2e1c214
--- /dev/null
+++ b/LegoArt.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30621.155
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LegoArt", "LegoArt\LegoArt.csproj", "{1D754A7E-DB2F-4A79-83B8-BF64A7130CCC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1D754A7E-DB2F-4A79-83B8-BF64A7130CCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D754A7E-DB2F-4A79-83B8-BF64A7130CCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D754A7E-DB2F-4A79-83B8-BF64A7130CCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D754A7E-DB2F-4A79-83B8-BF64A7130CCC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E48F3C4B-F649-4D65-AE06-10725BDFF022}
+ EndGlobalSection
+EndGlobal
diff --git a/LegoArt/App.xaml b/LegoArt/App.xaml
new file mode 100644
index 0000000..2a0476b
--- /dev/null
+++ b/LegoArt/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/LegoArt/App.xaml.cs b/LegoArt/App.xaml.cs
new file mode 100644
index 0000000..d710395
--- /dev/null
+++ b/LegoArt/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace LegoArt
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/LegoArt/AssemblyInfo.cs b/LegoArt/AssemblyInfo.cs
new file mode 100644
index 0000000..8b5504e
--- /dev/null
+++ b/LegoArt/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/LegoArt/LegoArt.csproj b/LegoArt/LegoArt.csproj
new file mode 100644
index 0000000..5425b37
--- /dev/null
+++ b/LegoArt/LegoArt.csproj
@@ -0,0 +1,13 @@
+
+
+
+ WinExe
+ netcoreapp3.1
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LegoArt/LegoArt.csproj.user b/LegoArt/LegoArt.csproj.user
new file mode 100644
index 0000000..644b0a6
--- /dev/null
+++ b/LegoArt/LegoArt.csproj.user
@@ -0,0 +1,14 @@
+
+
+
+
+
+ Designer
+
+
+
+
+ Designer
+
+
+
\ No newline at end of file
diff --git a/LegoArt/LegoColorInfo.cs b/LegoArt/LegoColorInfo.cs
new file mode 100644
index 0000000..7a0b9b1
--- /dev/null
+++ b/LegoArt/LegoColorInfo.cs
@@ -0,0 +1,19 @@
+using System.Windows.Media;
+
+namespace LegoArt
+{
+ public class LegoColorInfo
+ {
+ public Color Color { get; private set; }
+ public int LegoNumber { get; private set; }
+ public int HaveCount { get; private set; }
+ public int NeedCount { get; set; }
+
+ public LegoColorInfo(Color color, int number, int haveCount)
+ {
+ Color = color;
+ LegoNumber = number;
+ HaveCount = haveCount;
+ }
+ }
+}
diff --git a/LegoArt/LegoColorService.cs b/LegoArt/LegoColorService.cs
new file mode 100644
index 0000000..6e604de
--- /dev/null
+++ b/LegoArt/LegoColorService.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Media;
+
+namespace LegoArt
+{
+ public class LegoColorService
+ {
+ public List LegoColors { get; private set; }
+
+ public LegoColorService()
+ {
+ LegoColors = new List();
+
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(0, 0, 0), 1, 698));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(102, 101, 96), 2, 141));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(167, 166, 162), 3, 51));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(246, 246, 248), 4, 149));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(0, 53, 94), 5, 121));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(101, 135, 162), 6, 52));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(121, 196, 236), 7, 57));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(253, 104, 0), 8, 74));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(255, 170, 0), 9, 65));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(229, 205, 135), 10, 283));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(163, 129, 93), 11, 137));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(196, 115, 54), 12, 29));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(206, 81, 0), 13, 85));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(119, 40, 0), 14, 250));
+ LegoColors.Add(new LegoColorInfo(Color.FromRgb(66, 23, 3), 15, 554));
+ }
+
+ public LegoColorInfo GetColorInfo(Color color)
+ {
+ return LegoColors.Single(l => l.Color == color);
+ }
+ }
+}
diff --git a/LegoArt/MainWindow.xaml b/LegoArt/MainWindow.xaml
new file mode 100644
index 0000000..8a112d3
--- /dev/null
+++ b/LegoArt/MainWindow.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LegoArt/MainWindow.xaml.cs b/LegoArt/MainWindow.xaml.cs
new file mode 100644
index 0000000..39844ec
--- /dev/null
+++ b/LegoArt/MainWindow.xaml.cs
@@ -0,0 +1,127 @@
+using Microsoft.Win32;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Shapes;
+
+namespace LegoArt
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ private void btnImageChooser_Click(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new OpenFileDialog();
+ if (openFileDialog.ShowDialog() == true)
+ {
+ tbImagePath.Text = openFileDialog.FileName;
+ LoadImage(openFileDialog.FileName);
+ }
+ }
+
+ private void LoadImage(string path)
+ {
+ var legoColorService = new LegoColorService();
+
+ var bitmap = new System.Drawing.Bitmap(path);
+ var width = bitmap.Width;
+ var height = bitmap.Height;
+ for (int h = 0; h < height; h++)
+ {
+ for (int w = 0; w < width; w++)
+ {
+ var clr = bitmap.GetPixel(h, w);
+ var legoColor = ConvertDrawingToWindowsMediaColor(clr);
+ var legoColorInfo = legoColorService.GetColorInfo(legoColor);
+ legoColorInfo.NeedCount++;
+ }
+ }
+
+ parentStackPanel.Children.Clear();
+
+ AddLine(Colors.White, "Have", "Needed", "RGB", "#", "Difference", Colors.White);
+
+ var sortedColors = legoColorService.LegoColors.OrderBy(c => c.LegoNumber).ToList();
+ for (int i = 0; i < sortedColors.Count; i++)
+ {
+ var color = sortedColors[i].Color;
+ var textRgb = $"{color.R};{color.G};{color.B}";
+ var difference = sortedColors[i].HaveCount - sortedColors[i].NeedCount;
+ var statusColor = difference < 0 ? Colors.Red : Colors.Green;
+ AddLine(color, sortedColors[i].HaveCount.ToString(), sortedColors[i].NeedCount.ToString(), textRgb, sortedColors[i].LegoNumber.ToString(), difference.ToString(), statusColor);
+ }
+
+ var have = legoColorService.LegoColors.Sum(l => l.HaveCount);
+ var needed = legoColorService.LegoColors.Sum(l => l.NeedCount);
+ AddLine(Colors.White, have.ToString(), needed.ToString(), "Total:", "", "", Colors.White);
+ }
+
+ private void AddLine(Color color, string textHave, string textNeed, string textRgb, string textNumber, string textDifference, Color statusColor)
+ {
+ var rect = new Rectangle();
+ rect.Width = 20;
+ rect.Height = 20;
+ rect.Fill = new SolidColorBrush(color);
+
+ var textBlockHave = new TextBlock();
+ textBlockHave.Width = 40;
+ textBlockHave.Height = 20;
+ textBlockHave.TextAlignment = TextAlignment.Center;
+ textBlockHave.Text = textHave;
+
+ var textBlockNeed = new TextBlock();
+ textBlockNeed.Width = 50;
+ textBlockNeed.Height = 20;
+ textBlockNeed.TextAlignment = TextAlignment.Center;
+ textBlockNeed.Text = textNeed;
+
+ var textBlockRgb = new TextBlock();
+ textBlockRgb.Width = 100;
+ textBlockRgb.Height = 20;
+ textBlockRgb.TextAlignment = TextAlignment.Left;
+ textBlockRgb.Text = textRgb;
+
+ var legoNumber = new TextBlock();
+ legoNumber.Width = 20;
+ legoNumber.Height = 20;
+ legoNumber.TextAlignment = TextAlignment.Center;
+ legoNumber.Text = textNumber;
+
+ var differenceTextBlock = new TextBlock();
+ differenceTextBlock.Width = 55;
+ differenceTextBlock.Height = 20;
+ differenceTextBlock.TextAlignment = TextAlignment.Center;
+ differenceTextBlock.Text = textDifference;
+
+ var status = new Rectangle();
+ status.Width = 20;
+ status.Height = 20;
+ status.Fill = new SolidColorBrush(statusColor);
+
+ var stackPanel = new StackPanel();
+ stackPanel.Orientation = Orientation.Horizontal;
+ stackPanel.Margin = new Thickness(2, 2, 2, 2);
+ stackPanel.Children.Add(legoNumber);
+ stackPanel.Children.Add(rect);
+ stackPanel.Children.Add(textBlockRgb);
+ stackPanel.Children.Add(textBlockHave);
+ stackPanel.Children.Add(textBlockNeed);
+ stackPanel.Children.Add(differenceTextBlock);
+ stackPanel.Children.Add(status);
+ parentStackPanel.Children.Add(stackPanel);
+ }
+
+ private Color ConvertDrawingToWindowsMediaColor(System.Drawing.Color inputColor)
+ {
+ return Color.FromArgb(inputColor.A, inputColor.R, inputColor.G, inputColor.B);
+ }
+ }
+}