private void PrepareSLBitmap() { if (slBitmap != null) { slBitmap.Dispose(); } int width = Math.Min(ClientSize.Width, ClientSize.Height) / 2; if (width < 10) { slBitmap = null; return; } // Prepare Bitmap slBitmap = new Bitmap(width, width); BitmapData bmData; byte[] bytes; BitmapReadBytes(slBitmap, out bytes, out bmData); for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { Color c = ColorMath.HslToRgb(new HslColor(hue, (byte)(x * 255 / width), (byte)(y * 255 / width))); BitmapSetPixel(bytes, bmData, x, y, c); } } BitmapWriteBytes(slBitmap, bytes, bmData); }
//protected override void OnPaintBackground(PaintEventArgs pevent) //{ // if (VisualStyleRenderer.IsSupported) // { // // The VisualStyleElement does not matter, we're only drawing the parent's background // VisualStyleRenderer r = new VisualStyleRenderer(VisualStyleElement.Window.Dialog.Normal); // r.DrawParentBackground(pevent.Graphics, ClientRectangle, this); // } // else // { // base.OnPaintBackground(pevent); // } //} protected override void OnPaint(PaintEventArgs pe) { if (!hueMode) { if (color1.A < 255 || color2.A < 255) { Color backColor1 = Color.WhiteSmoke; Color backColor2 = Color.Silver; int size = 2 * 3; using (var bmp = new Bitmap(size, size)) { for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) { if (x < bmp.Width / 2 && y < bmp.Height / 2 || x >= bmp.Width / 2 && y >= bmp.Height / 2) { bmp.SetPixel(x, y, backColor1); } else { bmp.SetPixel(x, y, backColor2); } } } using (Brush b = new TextureBrush(bmp)) { pe.Graphics.FillRectangle(b, new Rectangle(paddingH, 0, Width - 2 * paddingH, Height - marginBottom)); } } } if (colorMid.IsEmpty) { var gradient = new LinearGradientBrush(new Point(), new Point(Width, 0), color1, color2); pe.Graphics.FillRectangle(gradient, new Rectangle(paddingH, 0, Width - 2 * paddingH, Height - marginBottom)); gradient.Dispose(); } else { var gradient = new LinearGradientBrush(new Point(), new Point(Width / 2, 0), color1, colorMid); pe.Graphics.FillRectangle(gradient, new Rectangle(paddingH, 0, Width / 2 - paddingH, Height - marginBottom)); gradient.Dispose(); gradient = new LinearGradientBrush(new Point(Width / 2, 0), new Point(Width, 0), colorMid, color2); pe.Graphics.FillRectangle(gradient, new Rectangle(Width / 2, 0, Width / 2 - paddingH, Height - marginBottom)); gradient.Dispose(); } } else { for (int x = paddingH; x < Width - paddingH; x++) { var h = (byte)Math.Round((double)(x - paddingH) / (Width - paddingH) * 255); using (var p = new Pen(ColorMath.HslToRgb(new HslColor(h, 255, 128)))) { pe.Graphics.DrawLine(p, x, 0, x, Height - marginBottom); } } } pe.Graphics.InterpolationMode = InterpolationMode.High; pe.Graphics.SmoothingMode = SmoothingMode.HighQuality; double d = (double)ratio / 255; int x0 = (int)((Width - 1 - 2 * paddingH) * d) + paddingH; int y0 = Height - 7; int triangleWidth = 5; int triangleHeight = 9; var trianglePath = new GraphicsPath(); trianglePath.AddLine(x0 - triangleWidth, y0 + triangleHeight, x0 + 0, y0 + 0); trianglePath.AddLine(x0 + 0, y0 + 0, x0 + triangleWidth, y0 + triangleHeight); trianglePath.CloseFigure(); var triangleBrush = new SolidBrush(Color.Black); pe.Graphics.FillPath(triangleBrush, trianglePath); triangleBrush.Dispose(); var trianglePen = new Pen(SystemColors.Control); pe.Graphics.DrawPath(trianglePen, trianglePath); trianglePen.Dispose(); trianglePath.Dispose(); }
private void PrepareWheelBitmap() { if (wheelBitmap != null) { wheelBitmap.Dispose(); } int width = Math.Min(ClientSize.Width, ClientSize.Height); var center = new Point(width / 2, width / 2); if (width < 10) { wheelBitmap = null; return; } // Prepare Bitmap wheelBitmap = new Bitmap(width, width); // Fill background Graphics g = Graphics.FromImage(wheelBitmap); using (Brush b = new SolidBrush(Color.Transparent)) { g.FillRectangle(b, 0, 0, width, width); } // Paint outer color wheel double minDist = width / 2 * 0.78; double maxDist = width / 2 - 1; double factor = 128.0 / Math.PI; // map -pi...pi to 0...255 => map 0...pi to 0...128 BitmapData bmData; byte[] bytes; BitmapReadBytes(wheelBitmap, out bytes, out bmData); for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { double dist = GetDistance(new Point(x, y), center); byte alpha; if (dist < minDist - 0.5) { alpha = 0; } else if (dist < minDist + 0.5) { alpha = (byte)((0.5 - minDist + dist) * 255); } else if (dist < maxDist - 0.5) { alpha = 255; } else if (dist < maxDist + 0.5) { alpha = (byte)((0.5 + maxDist - dist) * 255); } else { alpha = 0; } if (alpha > 0) { double radAngle = Math.Atan2(y - center.Y, x - center.X); // -pi -> -180° -> 192 // -pi/2 -> -90° -> 128 // 0 -> 0° -> 64 // pi/2 -> 90° -> 0 // pi -> 180° -> 192 // // y = a * x + t; // a = -1 // t = 192 var hue = (byte)Mod((int)(-factor * radAngle + 192), 256); Color c = Color.FromArgb(alpha, ColorMath.HslToRgb(new HslColor(hue, 255, 128))); BitmapSetPixel(bytes, bmData, x, y, c); } } } BitmapWriteBytes(wheelBitmap, bytes, bmData); }
//protected override void OnPaintBackground(PaintEventArgs pevent) //{ // if (VisualStyleRenderer.IsSupported) // { // // The VisualStyleElement does not matter, we're only drawing the parent's background // VisualStyleRenderer r = new VisualStyleRenderer(VisualStyleElement.Window.Dialog.Normal); // r.DrawParentBackground(pevent.Graphics, ClientRectangle, this); // } // else // { // base.OnPaintBackground(pevent); // } //} // NOTE: Other solution: http://dotnetrix.co.uk/custom.htm#tip3 protected override void OnPaint(PaintEventArgs pe) { // Draw outer color wheel bitmap if (wheelBitmap != null) { pe.Graphics.DrawImage(wheelBitmap, new Point()); } // Draw inner color bitmap if (slBitmap != null) { pe.Graphics.DrawImage(slBitmap, new Point(slBitmap.Width / 2, slBitmap.Width / 2)); } pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // Draw hue marker double radAngle = (double)hue / 128 * Math.PI + Math.PI / 2; // sin(angle) = y / d // cos(angle) = x / d double d = 0.89 * wheelBitmap.Width / 2; var x = (int)Math.Round(d * Math.Cos(radAngle)); var y = (int)-Math.Round(d * Math.Sin(radAngle)); // Map center-relative coordinates to window coordinates x += wheelBitmap.Width / 2; y += wheelBitmap.Width / 2; Color c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(hue, 255, 128))) > 128 ? Color.Black : Color.White; using (var p = new Pen(c)) { pe.Graphics.DrawEllipse(p, x - 3, y - 3, 6, 6); } // Draw secondary hue markers if (secondaryHues != null) { foreach (byte sHue in secondaryHues) { radAngle = (double)sHue / 128 * Math.PI + Math.PI / 2; // sin(angle) = y / d // cos(angle) = x / d d = 0.89 * wheelBitmap.Width / 2; x = (int)Math.Round(d * Math.Cos(radAngle)); y = (int)-Math.Round(d * Math.Sin(radAngle)); // Map center-relative coordinates to window coordinates x += wheelBitmap.Width / 2; y += wheelBitmap.Width / 2; c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(sHue, 255, 128))) > 128 ? Color.Black : Color.White; //using (Pen p = new Pen(Color.FromArgb(128, c))) //{ // pe.Graphics.DrawRectangle(p, x - 2, y - 2, 4, 4); //} using (Brush b = new SolidBrush(Color.FromArgb(128, c))) { pe.Graphics.FillRectangle(b, x - 2, y - 2, 4, 4); } } } // Draw inner color marker x = slBitmap.Width / 2 + saturation * (slBitmap.Width - 1) / 255; y = slBitmap.Width / 2 + lightness * (slBitmap.Width - 1) / 255; c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(hue, saturation, lightness))) > 128 ? Color.Black : Color.White; using (var p = new Pen(c)) { pe.Graphics.DrawEllipse(p, x - 3, y - 3, 6, 6); } }