static public Rgba32 FromHsl(Hsla32 source) { var result = new Rgba32(source.Width, source.Height); var rgb = result.Data; var hsl = source.Data; for (int i = 0; i < hsl.Length; i += 4) { rgb[i + Alpha] = (byte)(hsl[i + Hsla32.Alpha] * byte.MaxValue); var hue = hsl[i + Hsla32.Hue]; var saturation = hsl[i + Hsla32.Saturation]; var lightness = hsl[i + Hsla32.Lightness]; if (Math.Abs(saturation) < 1e-4F) { // gray scale rgb[i + Red] = rgb[i + Green] = rgb[i + Blue] = (byte)(lightness * byte.MaxValue); } else { var var2 = lightness < 0.5 ? lightness * (1.0F + saturation) : (lightness + saturation) - (saturation * lightness); var var1 = 2 * lightness - var2; rgb[i + Red] = (byte)(byte.MaxValue * hue2Rgb(var1, var2, hue + 1F / 3)); rgb[i + Green] = (byte)(byte.MaxValue * hue2Rgb(var1, var2, hue)); rgb[i + Blue] = (byte)(byte.MaxValue * hue2Rgb(var1, var2, hue - 1F / 3)); } } return(result); }
static public Hsla32 FromPbra32(byte[] data, int width) { Debug.Assert(data.Length % width == 0); const int red = Rgba32.Red, green = Rgba32.Green, blue = Rgba32.Blue; var height = data.Length / width / Rgba32.Dpp; var result = new Hsla32(width, height); var hsl = result.Data; Debug.Assert(hsl.Length == data.Length); for (int pixel = 0; pixel < data.Length; pixel += Dpp) { var realRed = (float)data[pixel + red] / byte.MaxValue; var realGreen = (float)data[pixel + green] / byte.MaxValue; var realBlue = (float)data[pixel + blue] / byte.MaxValue; var minColorness = Math.Min(Math.Min(realRed, realGreen), realBlue); var maxColorness = Math.Max(Math.Max(realRed, realGreen), realBlue); var diffColorness = maxColorness - minColorness; hsl[pixel + Alpha] = (float)data[pixel + Rgba32.Alpha] / byte.MaxValue; var light = (maxColorness + minColorness) / 2; hsl[pixel + Lightness] = light; if (Math.Abs(diffColorness) < 1e-4F) { //This is a gray, no chroma... hsl[pixel + Hue] = hsl[pixel + Saturation] = 0; } else { //Chromatic data... hsl[pixel + Saturation] = (light < 0.5)? diffColorness / (maxColorness + minColorness) : diffColorness / (2 - maxColorness - minColorness); var del_R = (((maxColorness - realRed) / 6) + (diffColorness / 2)) / diffColorness; var del_G = (((maxColorness - realGreen) / 6) + (diffColorness / 2)) / diffColorness; var del_B = (((maxColorness - realBlue) / 6) + (diffColorness / 2)) / diffColorness; if (realRed == maxColorness) { hsl[pixel + Hue] = del_B - del_G; } else if (realGreen == maxColorness) { hsl[pixel + Hue] = 1.0F / 3 + del_R - del_B; } else if (realBlue == maxColorness) { hsl[pixel + Hue] = 2.0F / 3 + del_G - del_R; } if (hsl[pixel + Hue] < 0) { hsl[pixel + Hue] += 1.0F; } if (hsl[pixel + Hue] > 1) { hsl[pixel + Hue] -= 1.0F; } } } return(result); }