/// <summary> /// RGBカラーからLCHカラースベースへ変換する /// </summary> /// <param name="rgb">RGBカラー</param> /// <returns>LCHカラースベース</returns> internal static Lch ToColor(Rgb rgb) { Lch lch = new Lch(); Lab lab = LabConverter.ToColor(rgb); var h = Math.Atan2(lab.B, lab.A); if (h > 0) { h = (h / Math.PI) * 180.0; } else { h = 360 - (Math.Abs(h) / Math.PI) * 180.0; } if (h < 0) { h += 360.0; } else if (h >= 360) { h -= 360.0; } lch.L = lab.L; lch.C = Math.Sqrt(lab.A * lab.A + lab.B * lab.B); lch.H = h; return(lch); }
/// <summary> /// RGBカラーからPCCSカラースベースへ変換する /// </summary> /// <param name="rgb">RGBカラー</param> /// <returns>PCCSカラースベース</returns> internal static string ToColor(Rgb rgb) { Lch lch = LchConverter.ToColor(rgb); var q = Table.Select(x => new { diff = Math.Abs(x.Lch.L - lch.L) + Math.Abs(x.Lch.C - lch.C) + Math.Abs(x.Lch.H - lch.H), self = x }); var min = q.Min(x => x.diff); var PCCS = q.Where(x => x.diff == min).FirstOrDefault().self; return(PCCS.Tone); }
internal static Lch YxyToLch(Yxy yxy) { double X = yxy.Y2 == 0 ? 0 : yxy.X * (yxy.Y1 / yxy.Y2); double Y = yxy.Y1; double Z = (1.0 - yxy.X - yxy.Y2) * (yxy.Y1 / yxy.Y2); X /= 0.95047; Y /= 1.0; Z /= 1.08883; double FX = X > 0.008856f ? Math.Pow(X, 1.0f / 3.0f) : (7.787f * X + 0.137931f); double FY = Y > 0.008856f ? Math.Pow(Y, 1.0f / 3.0f) : (7.787f * Y + 0.137931f); double FZ = Z > 0.008856f ? Math.Pow(Z, 1.0f / 3.0f) : (7.787f * Z + 0.137931f); Lab lab = new Lab(); lab.L = Y > 0.008856f ? (116.0f * FY - 16.0f) : (903.3f * Y); lab.A = 500f * (FX - FY); lab.B = 200f * (FY - FZ); var h = Math.Atan2(lab.B, lab.A); if (h > 0) { h = (h / Math.PI) * 180.0; } else { h = 360 - (Math.Abs(h) / Math.PI) * 180.0; } if (h < 0) { h += 360.0; } else if (h >= 360) { h -= 360.0; } Lch lch = new Lch(); lch.L = lab.L; lch.C = Math.Sqrt(lab.A * lab.A + lab.B * lab.B); lch.H = h; return(lch); }
public PCCSTable() { try { string text = DependencyService.Get <IData>().GetData("PCCSAll.dat"); string[] line = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); if (line.Length > 0) { int count = 0; IList <PCCSDat> list = new List <PCCSDat>(); foreach (string str in line) { if (count == 0) { count++; continue; } // 1行目処理しない string[] part = str.Split(new char[] { ',', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (part.Length > 0) { PCCSDat data = new PCCSDat(); data.Tone = part[0].ToString(); Rgb rgb = new Rgb(); rgb.R = System.Convert.ToInt16(part[1]); rgb.G = System.Convert.ToInt16(part[2]); rgb.B = System.Convert.ToInt16(part[3]); data.Rgb = rgb; Lch lch = new Lch(); lch = LchConverter.ToColor(rgb); data.Lch = lch; list.Add(data); } } items = list.AsQueryable(); } } catch (Exception e) { throw e; } }
/// <summary> /// RGBカラーからMUNSELLカラースベースへ変換する /// </summary> /// <param name="rgb">RGBカラー</param> /// <returns>MUNSELLカラースベース</returns> internal static Munsell ToColor(Rgb rgb) { Munsell item = new Munsell(); Lch lch = LchConverter.ToColor(rgb); if (rgb.R == rgb.G && rgb.G == rgb.B) { Lab lab = LabConverter.ToColor(rgb); item.H = new MunsellHue { Base = HueBase.N }; item.V = Math.Round(ConvertLtoV(lab.L), 1); return(item); } var q = Table.Select(x => new { diff = Math.Abs(x.Lch.L - lch.L) + Math.Abs(x.Lch.C - lch.C) + Math.Abs(x.Lch.H - lch.H), self = x }); var min = q.Min(x => x.diff); var munsell = q.Where(x => x.diff == min).FirstOrDefault().self; if (min < 3.0) { item.H = munsell.H; item.V = munsell.V; item.C = munsell.C; return(item); } var hue = new MunsellHue { Base = munsell.H.Base, Number = munsell.H.Number }; MunsellHue newHue; if (munsell.Lch.H > lch.H) { hue.Number -= 2.5; newHue = new MunsellHue { Base = hue.Base, Number = hue.Number }; } else { hue.Number += 2.5; newHue = new MunsellHue { Base = munsell.H.Base, Number = munsell.H.Number }; } var munsellX = FindMunsell(hue, munsell.V, munsell.C, true); newHue.Number += Math.Round((lch.H - Math.Min(munsell.Lch.H, munsellX.Lch.H)) / Math.Abs(munsell.Lch.H - munsellX.Lch.H) * 2.5, 1, MidpointRounding.AwayFromZero); double newChroma; //彩度max min var c = Table.Where(x => x.H == munsell.H && x.V == munsell.V) .GroupBy(x => x.V).Select(x => new { min = x.Min(y => y.C), max = x.Max(y => y.C) }).First(); if (c.min < munsell.C && munsell.C < c.max) { var chroma = munsell.Lch.C > lch.C ? munsell.C - 2.0 : munsell.C + 2.0; var munsellY = FindMunsell(munsell.H, munsell.V, chroma); newChroma = Math.Round(Math.Min(munsell.C, munsellY.C) + (lch.C - Math.Min(munsell.Lch.C, munsellY.Lch.C)) / Math.Abs(munsell.Lch.C - munsellY.Lch.C) * 2.0, 1, MidpointRounding.AwayFromZero); } else { newChroma = Math.Round(munsell.C / munsell.Lch.C * lch.C, 1, MidpointRounding.AwayFromZero); } var newValue = Math.Round(ConvertLtoV(lch.L), 1, MidpointRounding.AwayFromZero); item.H = newHue; item.C = newChroma; item.V = newValue; return(item); }