aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs')
-rw-r--r--Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs407
1 files changed, 407 insertions, 0 deletions
diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs
new file mode 100644
index 000000000..042350cb0
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.JobsV2/Models/VisualOffsetModel.cs
@@ -0,0 +1,407 @@
+using ColorMine.ColorSpaces;
+using Colourful;
+using Colourful.Conversion;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using Tango.Core.Commands;
+using Tango.SharedUI;
+
+namespace Tango.PPC.Jobs.Models
+{
+
+ public class VisualOffsetModel : ViewModel
+ {
+ public enum TypeColorCorrection
+ {
+ Lightness = 1,
+ Chroma = 2,
+ Hue = 3,
+ }
+
+ public class VisualLCHOffset : ViewModel
+ {
+ public TypeColorCorrection ColorType { get; set; }
+
+ public int Offset { get; set; }
+
+ public double L { get; set; }
+ public double C { get; set; }
+ public double H { get; set; }
+
+ public SolidColorBrush ColorBrush
+ {
+ get
+ {
+ Lch lch = new Lch() { L = L, C = C, H = H };
+ IRgb RGB = lch.ToRgb();
+ return new SolidColorBrush() { Color = Color.FromRgb(System.Convert.ToByte(RGB.R), System.Convert.ToByte(RGB.G), System.Convert.ToByte(RGB.B)) };
+ }
+ }
+
+ private bool _isVisible;
+
+ public bool IsVisible
+ {
+ get { return _isVisible; }
+ set
+ {
+ _isVisible = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+
+ public VisualLCHOffset(TypeColorCorrection colorType, int offset)
+ {
+ ColorType = colorType;
+ Offset = offset;
+ }
+
+ public void Init(Lch lch)
+ {
+ L = lch.L;
+ C = lch.C;
+ H = lch.H;
+ RaisePropertyChanged( nameof(ColorBrush));
+ }
+ }
+
+ #region Property
+
+
+ private double _l;
+ public double L
+ {
+ get { return _l; }
+ set
+ {
+ if (_l != value)
+ {
+ _l = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+ private double _a;
+ public double A
+ {
+ get { return _a; }
+ set
+ {
+ if (_a != value)
+ {
+ _a = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+ private double _b;
+ public double B
+ {
+ get { return _b; }
+ set
+ {
+ if (_b != value)
+ {
+ _b = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+
+ public double C { get; set; }
+ public double H { get; set; }
+
+ private double _sourcel;
+ public double SourceL
+ {
+ get { return _sourcel; }
+ set {
+ if(_sourcel != value)
+ {
+ _sourcel = value;
+ RaisePropertyChangedAuto();
+ ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
+ }
+ }
+ }
+
+ private double _sourcea;
+ public double SourceA
+ {
+ get { return _sourcea; }
+ set
+ {
+ if (_sourcea != value)
+ {
+ _sourcea = value;
+ RaisePropertyChangedAuto();
+ ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
+ }
+ }
+ }
+
+ private double _sourceb;
+ public double SourceB
+ {
+ get { return _sourceb; }
+ set
+ {
+ if (_sourceb != value)
+ {
+ _sourceb = value;
+ RaisePropertyChangedAuto();
+ ManualCorrection(LightnessOffset, ChromaOffset, HueOffset);
+ }
+ }
+ }
+
+ private double _sourceh;
+ public double SourceH
+ {
+ get { return _sourceh; }
+ set
+ {
+ if (_sourceh != value)
+ {
+ _sourceh = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+
+ private double _sourcec;
+ public double SourceC
+ {
+ get { return _sourcec; }
+ set
+ {
+ if (_sourcec != value)
+ {
+ _sourcec = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+ }
+
+ public double LightnessOffset { get; set; }
+ public double ChromaOffset { get; set; }
+ public double HueOffset { get; set; }
+
+
+
+ public VisualLCHOffset MinLightness { get; set; }
+ public VisualLCHOffset MaxLightness { get; set; }
+ public VisualLCHOffset MinChroma { get; set; }
+ public VisualLCHOffset MaxChroma { get; set; }
+ public VisualLCHOffset MinHue { get; set; }
+ public VisualLCHOffset MaxHue { get; set; }
+
+ public SolidColorBrush SourceColorBrush
+ {
+ get
+ {
+ //Lch lch = new Lch() { L = L, C = C, H = H };
+ //IRgb RGB = lch.ToRgb();
+ Lab lab = new Lab(SourceL, SourceA, SourceB);
+ Rgb rgb = new Rgb(lab.ToRgb());
+ return new SolidColorBrush() { Color = Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B) };
+ }
+ }
+
+ public SolidColorBrush ManualColorBrush
+ {
+ get
+ {
+ //Lch lch = new Lch() { L = L, C = C, H = H };
+ //IRgb rgb = lch.ToRgb();
+ if(LightnessOffset == 0 && ChromaOffset == 0 && HueOffset == 0)
+ {
+ return SourceColorBrush;
+ }
+ Lab lab = new Lab(L, A, B);
+ Rgb rgb = new Rgb(lab.ToRgb());
+ return new SolidColorBrush() { Color = Color.FromRgb((byte)rgb.R, (byte)rgb.G, (byte)rgb.B) };
+ }
+ }
+
+ #endregion
+
+ public VisualOffsetModel()
+ {
+ MinLightness = new VisualLCHOffset(TypeColorCorrection.Lightness, -1);
+ MaxLightness = new VisualLCHOffset(TypeColorCorrection.Lightness, 1);
+ MinChroma = new VisualLCHOffset(TypeColorCorrection.Chroma, -1);
+ MaxChroma = new VisualLCHOffset(TypeColorCorrection.Chroma, 1);
+ MinHue = new VisualLCHOffset(TypeColorCorrection.Hue, -1);
+ MaxHue = new VisualLCHOffset(TypeColorCorrection.Hue, 1);
+
+ }
+
+ public void InitLAB(double l, double a, double b, double c, double h)
+ {
+ L = l;
+ A = a;
+ B = b;
+ C = c;
+ H = h;
+ LightnessOffset = ChromaOffset = HueOffset = 0;
+
+ _sourcel = l;
+ RaisePropertyChanged(nameof(SourceL));
+ _sourcea = a;
+ RaisePropertyChanged(nameof(SourceA));
+ _sourceb = b;
+ RaisePropertyChanged(nameof(SourceB));
+ _sourcec = c;
+ RaisePropertyChanged(nameof(SourceC));
+ _sourceh = h;
+ RaisePropertyChanged(nameof(SourceH));
+
+ Lch lch = Correction(-6, 0, 0);
+ MinLightness.Init(lch);
+ lch = Correction(6, 0, 0);
+ MaxLightness.Init(lch);
+ lch = Correction(0, -6, 0);
+ MinChroma.Init(lch);
+ lch = Correction(0, 6, 0);
+ MaxChroma.Init(lch);
+ lch = Correction(0, 0, -6);
+ MinHue.Init(lch);
+ lch = Correction(0, 0, 6);
+ MaxHue.Init(lch);
+
+ RaisePropertyChanged(nameof(SourceColorBrush));
+ RaisePropertyChanged(nameof(ManualColorBrush));
+ }
+
+ public void UpdateSourceLAB(double l, double a, double b)
+ {
+ LabColor labColor = new LabColor(l, a, b);
+ var converter = new ColourfulConverter { WhitePoint = Illuminants.D65 };
+ var last_LCH = converter.ToLChab(labColor);
+ SourceL = l;
+ SourceA = a;
+ SourceB = b;
+ SourceC = last_LCH.C;
+ SourceH = last_LCH.h;
+ }
+
+ public void UpdateManualColors()
+ {
+ Lch lch = Correction(-6, 0, 0);
+ MinLightness.Init(lch);
+ lch = Correction(6, 0, 0);
+ MaxLightness.Init(lch);
+ lch = Correction(0, -6, 0);
+ MinChroma.Init(lch);
+ lch = Correction(0, 6, 0);
+ MaxChroma.Init(lch);
+ lch = Correction(0, 0, -6);
+ MinHue.Init(lch);
+ lch = Correction(0, 0, 6);
+ MaxHue.Init(lch);
+
+ RaisePropertyChanged(nameof(SourceColorBrush));
+ RaisePropertyChanged(nameof(ManualColorBrush));
+ }
+
+ /// <summary>
+ /// Manuals the correction. During change lightnessOffset, chromaOffset or hueOffset in app caused to change LAB of visual correction.
+ /// </summary>
+ /// <param name="lightnessOffset">The lightness offset.</param>
+ /// <param name="chromaOffset">The chroma offset.</param>
+ /// <param name="hueOffset">The hue offset.</param>
+ public void ManualCorrection(double lightnessOffset, double chromaOffset, double hueOffset)
+ {
+ Lch lch = Correction(lightnessOffset, chromaOffset, hueOffset);
+
+ L = lch.L;
+ A = lch.C * Math.Cos(lch.H * (Math.PI / 180));
+ B = lch.C * Math.Sin(lch.H * (Math.PI / 180));
+ RaisePropertyChanged(nameof(SourceColorBrush));
+ RaisePropertyChanged(nameof(ManualColorBrush));
+
+ }
+
+ /// <summary>
+ /// Calculate Lch on the specified lightness offset.
+ /// </summary>
+ /// <param name="lightnessOffset">The lightness offset.</param>
+ /// <param name="chromaOffset">The chroma offset.</param>
+ /// <param name="hueOffset">The hue offset.</param>
+ /// <returns></returns>
+ public Lch Correction( double lightnessOffset, double chromaOffset, double hueOffset)
+ {
+ //LightnessOffset = lightnessOffset;
+ //ChromaOffset = chromaOffset;
+ //HueOffset = hueOffset;
+
+ double L1 = SourceL;
+ double C1 = SourceC;
+ double H1 = SourceH;
+ if (H1 < 0)
+ H1 += 360;
+ double refX_C = C1;
+ ///lightness
+ double SL = 0;
+ if (L <= 16)
+ SL = 0.511;
+ else
+ SL = L1 * 0.040975 / (1 + 0.01765 * L1);
+ L1 += lightnessOffset * 2 * SL;
+ if(L1 > 100)
+ L1 = 100;
+ if(L1 < 0)
+ L1 = 0;
+
+ double SC = (0.638 + 0.0638 * refX_C / (1 + 0.0131 * refX_C));
+ C1 += chromaOffset * SC;
+ if (C1 > 128)
+ L1 = 128;
+ if (C1 < 0)
+ C1 = 0;
+
+ //double h1 = H1;
+ //if (h1 < 0)
+ // h1 = h1 + 360;
+ double refX_CQ = Math.Pow(refX_C, 4);
+ double refX_H = H1;
+ double refX_F = Math.Sqrt(refX_CQ / (refX_CQ + 1900));
+ double refX_T = 0;
+ if ((refX_H > 164) & (refX_H < 345))
+ refX_T = 0.56 + Math.Abs(0.2 * Math.Cos(Math.PI * (refX_H + 168) / 180));
+ else if ((refX_H >= 345) | (refX_H <= 164))
+ refX_T = 0.36 + Math.Abs(0.4 * Math.Cos(Math.PI * (refX_H + 35) / 180));
+
+ double refX_SC = (0.638 + 0.0638 * refX_C / (1 + 0.0131 * refX_C));
+ double refX_SH = refX_SC * (refX_T * refX_F + 1 - refX_F);
+ if(C1 != 0)
+ {
+ var argum = 1 - (refX_SH * refX_SH * hueOffset * hueOffset / (2 * C1 * C1));
+ if(argum < -1)
+ argum = -1;
+ if (argum > 1)
+ argum = 1;
+
+ double tmp = (180 / Math.PI) * Math.Acos(argum);
+ if (hueOffset < 0)//?
+ tmp *= -1;
+ H1 += tmp;
+ }
+ Lch lch = new Lch() { L = L1, C = C1, H = H1 };
+ return lch;
+
+ }
+
+
+ #region Converter
+
+
+ #endregion
+ }
+}