// this is where the actual colours are determined and set for the bulbs private void DoMainLoop(MaxLifxBulbController bulbController, ref int frames, DateTime start) { if (ShowUI) { var t = new Thread(() => { var form2 = new ScreenColourUI(SettingsCast, bulbController); /* (SettingsCast, bulbController.Bulbs);*/ form2.ShowDialog(); }); t.Start(); ShowUI = false; } frames++; // determine colours on screen // var screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); Color? avgColour = null; ScreenColorSet screenColourSet = null; foreach (var label in SettingsCast.SelectedLabels) { var multiFlag = false; var labelsAndLocations = SettingsCast.LabelsAndLocations.Single(x => x.Label == label); var location = labelsAndLocations.ScreenLocation; var zones = labelsAndLocations.Zones; // skip if set to None if (location == ScreenLocation.None) { continue; } if (zones > 1) { List <Rectangle> rectList = null; bool found = false; // try and grab the zones switch (location) { case ScreenLocation.SurroundCounterClockwise: found = ZoneAreas.TryGetValue(zones.ToString() + "ccw", out rectList); break; case ScreenLocation.SurroundClockwise: found = ZoneAreas.TryGetValue(zones.ToString() + "cw", out rectList); break; // for all other ScreenLocations we skip } if (found) { // our average colour pixel var screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb); var gdest = Graphics.FromImage(screenPixel); var gsrc = Graphics.FromHwnd(IntPtr.Zero); var srcData = screenPixel.LockBits( new Rectangle(0, 0, screenPixel.Width, screenPixel.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); screenPixel.UnlockBits(srcData); for (int i = 0; i < zones; i++) { var areaColour = GetScreenColourZones(rectList[i], srcData, gdest, gsrc); // code for using most dominant colour; doesn't look very good tbh /*var bmpScreenshot = new Bitmap(rectList[i].Width, rectList[i].Height, PixelFormat.Format32bppArgb); * var gfxScreenshot = Graphics.FromImage(bmpScreenshot); * gfxScreenshot.CopyFromScreen(rectList[i].X, rectList[i].Y, 0, 0, rectList[i].Size, CopyPixelOperation.SourceCopy); * Bitmap resized = new Bitmap(bmpScreenshot, new Size(bmpScreenshot.Width / 3, bmpScreenshot.Height / 3)); * var areaColour = dominantColour(resized);*/ if (areaColour != null) { Color avgZoneColour = (Color)areaColour; // Color isn't HSV, so need to convert double hue = 0; double saturation = 0; double brightness = 0; Utils.ColorToHSV((Color)avgZoneColour, out hue, out saturation, out brightness); brightness = (brightness * (SettingsCast.Brightness - SettingsCast.MinBrightness) + SettingsCast.MinBrightness); saturation = (saturation * (SettingsCast.Saturation - SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var zonePayload = new SetColourZonesPayload { start_index = new byte[1] { (byte)(i) }, end_index = new byte[1] { (byte)(i) }, Kelvin = (ushort)SettingsCast.Kelvin, TransitionDuration = (uint)(SettingsCast.Fade), Hue = (int)hue, Saturation = (ushort)saturation, Brightness = (ushort)brightness, // 0 for delayed apply; 1 for immediate (don't wait for other zones); apply = new byte[1] { 1 } }; // send bulbController.SetColour(label, zonePayload, false); } } multiFlag = true; } } // only do this calc if necessary if (!multiFlag) { // set once var screenPixel = new Bitmap(2, 2, PixelFormat.Format32bppArgb); var gdest = Graphics.FromImage(screenPixel); var gsrc = Graphics.FromHwnd(IntPtr.Zero); screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); // default is all avgColour = screenColourSet.all; switch (location) { case ScreenLocation.Top: avgColour = screenColourSet.top; break; case ScreenLocation.Bottom: avgColour = screenColourSet.bottom; break; case ScreenLocation.Left: avgColour = screenColourSet.left; break; case ScreenLocation.Right: avgColour = screenColourSet.right; break; case ScreenLocation.TopLeft: avgColour = screenColourSet.topleft; break; case ScreenLocation.TopRight: avgColour = screenColourSet.topright; break; case ScreenLocation.BottomLeft: avgColour = screenColourSet.bottomleft; break; case ScreenLocation.BottomRight: avgColour = screenColourSet.bottomright; break; } // Color isn't HSV, so need to convert double hue = 0; double saturation = 0; double brightness = 0; Utils.ColorToHSV((Color)avgColour, out hue, out saturation, out brightness); brightness = (brightness * (SettingsCast.Brightness - SettingsCast.MinBrightness) + SettingsCast.MinBrightness); saturation = (saturation * (SettingsCast.Saturation - SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var payload = new SetColourPayload { Kelvin = (ushort)SettingsCast.Kelvin, TransitionDuration = (uint)(SettingsCast.Fade), Hue = (int)hue, Saturation = (ushort)saturation, Brightness = (ushort)brightness }; bulbController.SetColour(label, payload, true); } // this is for when multizone apply is set to 0: need to send another packet to apply everything /*else { * var payload = new SetColourZonesPayload * { * start_index = new byte[1] { 0 }, * end_index = new byte[1] { 0 }, * Kelvin = 3500, * TransitionDuration = 0, * Hue = 0, * Saturation = 0, * Brightness = 0, * // ignore this payload and apply previous ones * apply = new byte[1] { 2 } * }; * bulbController.SetColourZoneFinder(label, payload); * //bulbController.SetColour(label, payload); * }*/ // } } Thread.Sleep(SettingsCast.Delay); }
private unsafe ScreenColorSet GetScreenColours(Point tl, Point br, Bitmap screenPixel, Graphics gdest, Graphics gsrc) { IntPtr hSrcDC; IntPtr hDC; var width = br.X - tl.X; if (width < 0) { width = 0 - width; } var height = br.Y - tl.Y; if (height < 0) { height = 0 - height; } if (height == 0 || width == 0) { return(null); } //var realtlx = 50;//tl.X < br.X ? tl.X : br.X; //var realtly = 50;//tl.Y < br.Y ? tl.Y : br.Y; Color topleft, bottomleft, topright, bottomright, top, bottom, left, right, all; ScreenColorSet returnValue; var thumbSize = new Size(2, 2); hSrcDC = gsrc.GetHdc(); hDC = gdest.GetHdc(); //var retval = BitBlt(hDC, 0, 0, width, height, hSrcDC, 0, 0, // (int) CopyPixelOperation.SourceCopy); SetStretchBltMode(hDC, 0x04); StretchBlt(hDC, 0, 0, thumbSize.Width, thumbSize.Height, hSrcDC, tl.X, tl.Y, width, height, (int)CopyPixelOperation.SourceCopy); gdest.ReleaseHdc(); gsrc.ReleaseHdc(); //screenPixel.Save("Pics\\" + DateTime.Now.ToString("hhmmss").Replace("/", "").Replace(":", "") + ".bmp"); var srcData = screenPixel.LockBits( new Rectangle(0, 0, screenPixel.Width, screenPixel.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var stride = srcData.Stride; var scan0 = srcData.Scan0; var p = (byte *)(void *)scan0; topleft = Color.FromArgb(255, p[2], p[1], p[0]); bottomleft = Color.FromArgb(255, p[stride + 2], p[stride + 1], p[stride + 0]); topright = Color.FromArgb(255, p[4 + 2], p[4 + 1], p[4 + 0]); bottomright = Color.FromArgb(255, p[stride + 4 + 2], p[stride + 4 + 1], p[stride + 4 + 0]); top = Color.FromArgb(255, (topleft.R + topright.R) / 2, (topleft.G + topright.G) / 2, (topleft.B + topright.B) / 2); bottom = Color.FromArgb(255, (bottomleft.R + bottomright.R) / 2, (bottomleft.G + bottomright.G) / 2, (bottomleft.B + bottomright.B) / 2); left = Color.FromArgb(255, (topleft.R + bottomleft.R) / 2, (topleft.G + bottomleft.G) / 2, (topleft.B + bottomleft.B) / 2); right = Color.FromArgb(255, (bottomright.R + topright.R) / 2, (bottomright.G + topright.G) / 2, (bottomright.B + topright.B) / 2); all = Color.FromArgb(255, (top.R + bottom.R) / 2, (top.G + bottom.G) / 2, (top.B + bottom.B) / 2); screenPixel.UnlockBits(srcData); returnValue = new ScreenColorSet { topleft = topleft, topright = topright, top = top, bottomleft = bottomleft, bottomright = bottomright, bottom = bottom, left = left, right = right, all = all }; return(returnValue); }
private unsafe ScreenColorSet GetScreenColours(Point tl, Point br, Bitmap screenPixel, Graphics gdest, Graphics gsrc) { IntPtr hSrcDC; IntPtr hDC; var width = br.X - tl.X; if (width < 0) { width = 0 - width; } var height = br.Y - tl.Y; if (height < 0) { height = 0 - height; } if (height == 0 || width == 0) { return(null); } //var realtlx = 50;//tl.X < br.X ? tl.X : br.X; //var realtly = 50;//tl.Y < br.Y ? tl.Y : br.Y; ScreenColorSet returnValue; var thumbSize = CaptureResolution; hSrcDC = gsrc.GetHdc(); hDC = gdest.GetHdc(); //var retval = BitBlt(hDC, 0, 0, width, height, hSrcDC, 0, 0, // (int) CopyPixelOperation.SourceCopy); SetStretchBltMode(hDC, 0x4); StretchBlt(hDC, 0, 0, thumbSize.Width, thumbSize.Height, hSrcDC, tl.X, tl.Y, width, height, (int)CopyPixelOperation.SourceCopy); gdest.ReleaseHdc(); gsrc.ReleaseHdc(); // var srcData = screenPixel.LockBits( new Rectangle(0, 0, screenPixel.Width, screenPixel.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); //screenPixel.Save("c:\\temp\\test.bmp"); var stride = srcData.Stride; var scan0 = srcData.Scan0; var p = (byte *)(void *)scan0; var returnColors = new Color[CaptureResolution.Width * CaptureResolution.Height]; for (var x = 0; x < CaptureResolution.Width; x++) { for (var y = 0; y < CaptureResolution.Height; y++) { returnColors[x + y * CaptureResolution.Height] = PixelToColour(x, y, p, stride); } } returnValue = new ScreenColorSet { colours = returnColors }; return(returnValue); }