/////////////////////////////////////////////////////////////////////////////////
// Paint.NET //
// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
// See src/Resources/Files/License.txt for full licensing and attribution //
// details. //
// . //
/////////////////////////////////////////////////////////////////////////////////
using System;
using System.Drawing;
namespace PaintDotNet{
/// <summary>
/// Adapted from:
/// "A Primer on Building a Color Picker User Control with GDI+ in Visual Basic .NET or C#"
/// http://www.msdnaa.net/Resources/display.aspx?ResID=2460
///
/// This class is only used by the ColorsForm and ColorWheel. Nothing else in this program
/// should be using it!
/// </summary>
[Serializable]
public struct RgbColor
{
// All values are between 0 and 255.
public int Red;
public int Green;
public int Blue;
public RgbColor(int R, int G, int B)
{
#if DEBUG
if (R < 0 || R > 255)
{
throw new ArgumentOutOfRangeException("R", R, "R must corrospond to a byte value");
}
if (G < 0 || G > 255)
{
throw new ArgumentOutOfRangeException("G", G, "G must corrospond to a byte value");
}
if (B < 0 || B > 255)
{
throw new ArgumentOutOfRangeException("B", B, "B must corrospond to a byte value");
}
#endif
Red = R;
Green = G;
Blue = B;
}
public static RgbColor FromHsv(HsvColor hsv)
{
return hsv.ToRgb();
}
public Color ToColor()
{
return Color.FromArgb(Red, Green, Blue);
}
public HsvColor ToHsv()
{
// In this function, R, G, and B values must be scaled
// to be between 0 and 1.
// HsvColor.Hue will be a value between 0 and 360, and
// HsvColor.Saturation and value are between 0 and 1.
double min;
double max;
double delta;
double r = (double) Red / 255;
double g = (double) Green / 255;
double b = (double) Blue / 255;
double h;
double s;
double v;
min = Math.Min(Math.Min(r, g), b);
max = Math.Max(Math.Max(r, g), b);
v = max;
delta = max - min;
if (max == 0 || delta == 0)
{
// R, G, and B must be 0, or all the same.
// In this case, S is 0, and H is undefined.
// Using H = 0 is as good as any...
s = 0;
h = 0;
}
else
{
s = delta / max;
if (r == max)
{
// Between Yellow and Magenta
h = (g - b) / delta;
}
else if (g == max)
{
// Between Cyan and Yellow
h = 2 + (b - r) / delta;
}
else
{
// Between Magenta and Cyan
h = 4 + (r - g) / delta;
}
}
// Scale h to be between 0 and 360.
// This may require adding 360, if the value
// is negative.
h *= 60;
if (h < 0)
{
h += 360;
}
// Scale to the requirements of this
// application. All values are between 0 and 255.
return new HsvColor((int)h, (int)(s * 100), (int)(v * 100));
}
public override string ToString()
{
return String.Format("({0}, {1}, {2})", Red, Green, Blue);
}
}
}
|