/// <summary> /// Convert an <see cref="HSBColor" /> value to an equivalent <see cref="Color" /> value. /// </summary> /// <remarks> /// This method is based on code from http://www.cs.rit.edu/~ncs/color/ by Eugene Vishnevsky. /// </remarks> /// <param name="hsbColor">The <see cref="HSBColor" /> struct to be converted</param> /// <returns>An equivalent <see cref="Color" /> struct, compatible with the GDI+ library</returns> public static Color ToRGB(HSBColor hsbColor) { Color rgbColor = Color.Black; // Determine which sector of the color wheel contains this hue // hsbColor.H ranges from 0 to 255, and there are 6 sectors, so 42.5 per sector int sector = (int)Math.Floor((double)hsbColor.H / 42.5); // Calculate where the hue lies within the sector for interpolation purpose double fraction = (double)hsbColor.H / 42.5 - (double)sector; double sFrac = (double)hsbColor.S / 255.0; byte p = (byte)(((double)hsbColor.B * (1.0 - sFrac)) + 0.5); byte q = (byte)(((double)hsbColor.B * (1.0 - sFrac * fraction)) + 0.5); byte t = (byte)(((double)hsbColor.B * (1.0 - sFrac * (1.0 - fraction))) + 0.5); switch (sector) { case 0: // red - yellow rgbColor = Color.FromArgb(hsbColor.A, hsbColor.B, t, p); break; case 1: // yellow - green rgbColor = Color.FromArgb(hsbColor.A, q, hsbColor.B, p); break; case 2: // green - cyan rgbColor = Color.FromArgb(hsbColor.A, p, hsbColor.B, t); break; case 3: // cyan - blue rgbColor = Color.FromArgb(hsbColor.A, p, q, hsbColor.B); break; case 4: // blue - magenta rgbColor = Color.FromArgb(hsbColor.A, t, p, hsbColor.B); break; case 5: default: // magenta - red rgbColor = Color.FromArgb(hsbColor.A, hsbColor.B, p, q); break; } return rgbColor; }
public Image TestChangeColor(Bitmap bmp, byte minHue,byte maxHue,byte newHue) { BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = bmpData.Stride * bmpData.Height; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); for (int c = 0; c < rgbValues.Length; c += 4) { HSBColor hsb = new HSBColor(Color.FromArgb( rgbValues[c + 3], rgbValues[c + 2], rgbValues[c + 1], rgbValues[c])); if (hsb.H >= minHue && hsb.H <= maxHue) { hsb.H = Convert.ToByte(newHue); } Color color = hsb.ToRGB(); rgbValues[c] = color.B; rgbValues[c + 1] = color.G; rgbValues[c + 2] = color.R; rgbValues[c + 3] = color.A; } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); return (Image)bmp; }
/// <summary> /// Convert a <see cref="Color" /> value to an equivalent <see cref="HSBColor" /> value. /// </summary> /// <remarks> /// This method is based on code from http://www.cs.rit.edu/~ncs/color/ by Eugene Vishnevsky. /// </remarks> /// <param name="rgbColor">The <see cref="Color" /> struct to be converted</param> /// <returns>An equivalent <see cref="HSBColor" /> struct</returns> public static HSBColor FromRGB(Color rgbColor) { double r = (double)rgbColor.R / 255.0; double g = (double)rgbColor.G / 255.0; double b = (double)rgbColor.B / 255.0; double min = Math.Min(Math.Min(r, g), b); double max = Math.Max(Math.Max(r, g), b); HSBColor hsbColor = new HSBColor(rgbColor.A, 0, 0, 0); hsbColor.B = (byte)(max * 255.0 + 0.5); double delta = max - min; if (max != 0.0) { hsbColor.S = (byte)(delta / max * 255.0 + 0.5); } else { hsbColor.S = 0; hsbColor.H = 0; return hsbColor; } double h; if (r == max) h = (g - b) / delta; // between yellow & magenta else if (g == max) h = 2 + (b - r) / delta; // between cyan & yellow else h = 4 + (r - g) / delta; // between magenta & cyan hsbColor.H = (byte)(h * 42.5); if (hsbColor.H < 0) hsbColor.H += 255; return hsbColor; }