static RgbToCieConverter() { var gamutA = new Gamut(new Point(0.704, 0.296), new Point(0.2151, 0.7106), new Point(0.138, 0.080)); var gamutB = new Gamut(new Point(0.675, 0.322), new Point(0.4090, 0.5180), new Point(0.167, 0.040)); var gamutC = new Gamut(new Point(0.692, 0.308), new Point(0.1700, 0.7000), new Point(0.153, 0.048)); //http://www.developers.meethue.com/documentation/supported-lights _gamutAssignment = new Dictionary<string, Gamut>(StringComparer.OrdinalIgnoreCase) { {"LCT001", gamutB}, {"LCT007", gamutB}, {"LCT010", gamutC}, {"LCT014", gamutC}, {"LCT002", gamutB}, {"LCT003", gamutB}, {"LCT011", gamutC}, {"LST001", gamutA}, {"LLC010", gamutA}, {"LLC011", gamutA}, {"LLC012", gamutA}, {"LLC006", gamutA}, {"LLC007", gamutA}, {"LLC013", gamutA}, {"LLM001", gamutB}, {"LLC020", gamutC}, {"LST002", gamutC} }; }
private static Point GetCentroid(Gamut gamut) { var x = (gamut.Red.X + gamut.Green.X + gamut.Blue.X) / 3d; var y = (gamut.Red.Y + gamut.Green.Y + gamut.Blue.Y) / 3d; return(new Point(x, y)); }
public double GetAverageY() { var imagePath = ImagePath; if (!File.Exists(imagePath)) { throw new FileNotFoundException(); } int core = ProcessingCore; using (var bitmap = new Bitmap(imagePath)) { // 対象領域を分割 int resolution = bitmap.Height / core; var rects = new Rectangle[core]; for (int i = 0; i < rects.Length - 1; i++) { rects[i] = new Rectangle(0, resolution * i, bitmap.Width, resolution); } rects[core - 1] = new Rectangle(0, resolution * (core - 1), bitmap.Width, bitmap.Height - resolution * (core - 1)); int bytesPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8; var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); var rgb = Task.WhenAll(rects.Select(async x => await ProcessUsingLockbitsAndUnsafe(bitmapData, bytesPerPixel, x))).Result; bitmap.UnlockBits(bitmapData); return(rgb.Select(x => Gamut.GetY(x.R, x.G, x.B)).Average()); } }
static RgbToCieConverter() { var gamutA = new Gamut(new Point(0.704, 0.296), new Point(0.2151, 0.7106), new Point(0.138, 0.080)); var gamutB = new Gamut(new Point(0.675, 0.322), new Point(0.4090, 0.5180), new Point(0.167, 0.040)); var gamutC = new Gamut(new Point(0.692, 0.308), new Point(0.1700, 0.7000), new Point(0.153, 0.048)); //http://www.developers.meethue.com/documentation/supported-lights _gamutAssignment = new Dictionary <string, Gamut>(StringComparer.OrdinalIgnoreCase) { { "LCT001", gamutB }, { "LCT007", gamutB }, { "LCT010", gamutC }, { "LCT014", gamutC }, { "LCT002", gamutB }, { "LCT003", gamutB }, { "LCT011", gamutC }, { "LST001", gamutA }, { "LLC010", gamutA }, { "LLC011", gamutA }, { "LLC012", gamutA }, { "LLC006", gamutA }, { "LLC007", gamutA }, { "LLC013", gamutA }, { "LLM001", gamutB }, { "LLC020", gamutC }, { "LST002", gamutC } }; }
public double GetAverageY() { var path = ImagePath; using (Image <Rgba32> image = Image.Load(path)) { var width = image.Width; var height = image.Height; ulong sumR = 0, sumG = 0, sumB = 0; for (int y = 0; y < height; y++) { foreach (var pixel in image.GetPixelRowSpan(y)) { sumB += pixel.B; sumG += pixel.G; sumR += pixel.R; } } var count = (double)(width * height); var aveR = sumR / count; var aveG = sumG / count; var aveB = sumB / count; return(Gamut.GetY(R: aveR, G: aveG, B: aveB)); } }
public static RGBColour XYtoRGB(Point point, string model) { if (model != null) { Gamut gamut = Gamut.ForModel(model); point = gamut.NearestContainedPoint(point); } point = Gamut.PhilipsWideGamut.NearestContainedPoint(point); double Y = 1.0; double X = (Y / point.y) * point.x; double Z = (Y / point.y) * point.z; double r = X * 1.656492 - Y * 0.354851 - Z * 0.255038; double g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152; double b = X * 0.051713 - Y * 0.121364 + Z * 1.011530; double maxComponent = Math.Max(Math.Max(r, g), b); if (maxComponent > 1.0) { r /= maxComponent; g /= maxComponent; b /= maxComponent; } r = Gamma(r); g = Gamma(g); b = Gamma(b); return(new RGBColour(r, g, b)); }
public static Point RgbToXY(RGBColour colour, string model) { double r = InverseGamma(colour.red); double g = InverseGamma(colour.green); double b = InverseGamma(colour.blue); double X = r * 0.664511f + g * 0.154324f + b * 0.162028f; double Y = r * 0.283881f + g * 0.668433f + b * 0.047685f; double Z = r * 0.000088f + g * 0.072310f + b * 0.986039f; Point xyPoint = new Point(0.0, 0.0); if ((X + Y + Z) > 0.0) { xyPoint = new Point(X / (X + Y + Z), Y / (X + Y + Z)); } if (model != null) { Gamut gamut = Gamut.ForModel(model); return(gamut.NearestContainedPoint(xyPoint)); } return(xyPoint); }
private static IEnumerable <LineSegment> GetLineSegments(Gamut gamut) { yield return(new LineSegment(gamut.Red, gamut.Green)); yield return(new LineSegment(gamut.Red, gamut.Blue)); yield return(new LineSegment(gamut.Blue, gamut.Green)); }
public double GetAverageY() { var imagePath = ImagePath; if (!File.Exists(imagePath)) { throw new FileNotFoundException(); } using (var bitmap = new Bitmap(imagePath)) { var(R, G, B) = ProcessUsingLockbitsAndUnsafeAndParallel(bitmap); return(Gamut.GetY(R, G, B)); } }
public double GetAverageY() { var imagePath = ImagePath; if (!File.Exists(imagePath)) { throw new FileNotFoundException(); } using (var bitmap = new Bitmap(imagePath)) { var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var(R, G, B) = ProcessUsingLockbitsAndUnsafe(bitmap, ref rect); return(Gamut.GetY(R, G, B)); } }
// 指定領域の平均輝度の読み込み private static double GetAverageY(BitmapImage bmp, ref Int32Rect rect) { if (bmp is null) { throw new ArgumentNullException(nameof(bmp)); } if (rect.Width * rect.Height == 0) { throw new ArgumentException("RectArea"); } int pixelsByte = (bmp.Format.BitsPerPixel + 7) / 8; // bit→Byte変換 int imageWidth = bmp.PixelWidth; int imageHeight = bmp.PixelHeight; int rectX = rect.X; int rectY = rect.Y; int rectArea = rect.Width * rect.Height; // 範囲制限(とりあえずで幅/高さを保つ方針で実装してます) if (imageWidth < rectX + rect.Width) { rectX = imageWidth - rect.Width; } if (imageHeight < rectY + rect.Height) { rectY = imageHeight - rect.Height; } var pixels = new byte[rectArea * pixelsByte]; var bitmapImage = bmp as BitmapSource; if (rectX != 0 || rectY != 0 || rect.Width != imageWidth || rect.Height != imageHeight) { bitmapImage = new CroppedBitmap(bmp, new Int32Rect(rectX, rectY, rect.Width, rect.Height)); } try { bitmapImage.CopyPixels(pixels, rect.Width * pixelsByte, 0); } catch (System.Runtime.InteropServices.COMException ex) { Trace.WriteLine(ex.Message); // 謎たまに起きる } // 1画素(カーソル用)の計算 if (rectArea == 1) { if (pixelsByte < 3) { //return new Gamut1(pixels[0]); } else { //return new Gamut1(pixels[0], pixels[1], pixels[2]); } } else { if (pixelsByte <= 1) { //return new Gamut2(pixels, new Size(rectWidth, rectHeight), pixelsByte); } else { var(R, G, B) = GetAverage(pixels, rect.Width, rect.Height, pixelsByte); return(Gamut.GetY(R, G, B)); } } return(0); }
private static IEnumerable<LineSegment> GetLineSegments(Gamut gamut) { yield return new LineSegment(gamut.Red, gamut.Green); yield return new LineSegment(gamut.Red, gamut.Blue); yield return new LineSegment(gamut.Blue, gamut.Green); }
private static Point GetCentroid(Gamut gamut) { var x = (gamut.Red.X + gamut.Green.X + gamut.Blue.X)/3d; var y = (gamut.Red.Y + gamut.Green.Y + gamut.Blue.Y)/3d; return new Point(x, y); }