アルゴリズム切り替えRGB、HSBカラー値
質問
を拝読させていただきました第 アルゴリズム切り替えRGB、HSBカラー値
Type RGBColor
Red As Byte
Green As Byte
Blue As Byte
End Type
Type HSBColor
Hue As Double
Saturation As Double
Brightness As Double
End Type
Function RGBToHSB(rgb As RGBColor) As HSBColor
Dim minRGB, maxRGB, Delta As Double
Dim h, s, b As Double
h = 0
minRGB = Min(Min(rgb.Red, rgb.Green), rgb.Blue)
maxRGB = Max(Max(rgb.Red, rgb.Green), rgb.Blue)
Delta = (maxRGB - minRGB)
b = maxRGB
If (maxRGB <> 0) Then
s = 255 * Delta / maxRGB
Else
s = 0
End If
If (s <> 0) Then
If rgb.Red = maxRGB Then
h = (CDbl(rgb.Green) - CDbl(rgb.Blue)) / Delta
Else
If rgb.Green = maxRGB Then
h = 2 + (CDbl(rgb.Blue) - CDbl(rgb.Red)) / Delta
Else
If rgb.Blue = maxRGB Then
h = 4 + (CDbl(rgb.Red) - CDbl(rgb.Green)) / Delta
End If
End If
End If
Else
h = -1
End If
h = h * 60
If h < 0 Then h = h + 360
RGBToHSB.Hue = h
RGBToHSB.Saturation = s * 100 / 255
RGBToHSB.Brightness = b * 100 / 255
End Function
Function HSBToRGB(hsb As HSBColor) As RGBColor
Dim maxRGB, Delta As Double
Dim h, s, b As Double
h = hsb.Hue / 60
s = hsb.Saturation * 255 / 100
b = hsb.Brightness * 255 / 100
maxRGB = b
If s = 0 Then
HSBToRGB.Red = 0
HSBToRGB.Green = 0
HSBToRGB.Blue = 0
Else
Delta = s * maxRGB / 255
If h > 3 Then
HSBToRGB.Blue = CByte(Round(maxRGB))
If h > 4 Then
HSBToRGB.Green = CByte(Round(maxRGB - Delta))
HSBToRGB.Red = CByte(Round((h - 4) * Delta)) + HSBToRGB.Green
Else
HSBToRGB.Red = CByte(Round(maxRGB - Delta))
HSBToRGB.Green = CByte(HSBToRGB.Red - Round((h - 4) * Delta))
End If
Else
If h > 1 Then
HSBToRGB.Green = CByte(Round(maxRGB))
If h > 2 Then
HSBToRGB.Red = CByte(Round(maxRGB - Delta))
HSBToRGB.Blue = CByte(Round((h - 2) * Delta)) + HSBToRGB.Red
Else
HSBToRGB.Blue = CByte(Round(maxRGB - Delta))
HSBToRGB.Red = CByte(HSBToRGB.Blue - Round((h - 2) * Delta))
End If
Else
If h > -1 Then
HSBToRGB.Red = CByte(Round(maxRGB))
If h > 0 Then
HSBToRGB.Blue = CByte(Round(maxRGB - Delta))
HSBToRGB.Green = CByte(Round(h * Delta)) + HSBToRGB.Blue
Else
HSBToRGB.Green = CByte(Round(maxRGB - Delta))
HSBToRGB.Blue = CByte(HSBToRGB.Green - Round(h * Delta))
End If
End If
End If
End If
End If
End Function
その人の投稿があった間違いがなかった精巧ない
いと思うので管理の必要がh以上5、例えば、色のR:130G:65億:111
If h > 5 Then
HSBToRGB.Red = CByte(Round(maxRGB))
If h > 6 Then
HSBToRGB.Blue= CByte(Round(maxRGB - Delta))
HSBToRGB.Green= CByte(Round((h - 6) * Delta)) HSBToRGB.Blue
Else
HSBToRGB.Green= CByte(Round(maxRGB - Delta))
HSBToRGB.Blue = CByte(HSBToRGB.Green- Round((h - 6) * Delta))
End If
をつけ加えればよいですこの曲のコードについて教えてください。のではないかと思い重なり合うように弊社RGB(私C#に変換)
...
if (s != 0) {
delta = s * maxRGB / 255;
if (h > 5)
rgb.Red = Convert.ToByte(Math.Round(maxRGB));
if (h > 6)
{
rgb.Green = Convert.ToByte(Math.Round(maxRGB - delta));
rgb.Blue = Convert.ToByte(rgb.Green - Math.Round((h - 6) * delta));
}
if (h > 3)
{
...
ものであると考えられるように、または
if (h > 6) { }
else if (h > 3) { }
解決
方法を構築します。純のColorオブジェクトはスターターでは、複数の回答を行な支援を逆変換し、HSB表色RGB).また、 Color.GetBrightness
実際に返します 軽さ, より明るさの値です。あの混乱の違いを、HSB/HSV、HSLのカラースペースが類似性(Wikipedia).かん色無事完了に終了するまでの間違ったアルゴリズムやモデルです。
元のコードを見たというヒント数のシナリオでの計算値のための色合いは、RGBカラーです。ちょっと私は追加だと考えてそうですが、最初のものが飛び出してもいながら修正)が飽和=0のとき、設定した色を-1になります。き後に掛ける色相による60ま-60、その後に追加することを360(If h < 0 Then h = h + 360
発の結果、300、正しくありません。
まるには、次のコードを使用します(VB.NET換とRGBとHSB(うしたHSV).その結果が確認されている非常に広く、その結果を及ぼしているが、これらによるPhotoshopのカラーピッカーからの報酬ではカラープロファイル).との大きな違いは投稿されたコードおよび鉱山(ほかの重要な部分を計算するの色合いがとう正規化のRGB値を0と1の間の計算ではなく、元の値は0~255までです。この非効率性と複数の変換は、元のコードで掲載しています。
Public Function RGBtoHSV(ByVal R As Integer, ByVal G As Integer, ByVal B As Integer) As HSV
''# Normalize the RGB values by scaling them to be between 0 and 1
Dim red As Decimal = R / 255D
Dim green As Decimal = G / 255D
Dim blue As Decimal = B / 255D
Dim minValue As Decimal = Math.Min(red, Math.Min(green, blue))
Dim maxValue As Decimal = Math.Max(red, Math.Max(green, blue))
Dim delta As Decimal = maxValue - minValue
Dim h As Decimal
Dim s As Decimal
Dim v As Decimal = maxValue
''# Calculate the hue (in degrees of a circle, between 0 and 360)
Select Case maxValue
Case red
If green >= blue Then
If delta = 0 Then
h = 0
Else
h = 60 * (green - blue) / delta
End If
ElseIf green < blue Then
h = 60 * (green - blue) / delta + 360
End If
Case green
h = 60 * (blue - red) / delta + 120
Case blue
h = 60 * (red - green) / delta + 240
End Select
''# Calculate the saturation (between 0 and 1)
If maxValue = 0 Then
s = 0
Else
s = 1D - (minValue / maxValue)
End If
''# Scale the saturation and value to a percentage between 0 and 100
s *= 100
v *= 100
''# Return a color in the new color space
Return New HSV(CInt(Math.Round(h, MidpointRounding.AwayFromZero)), _
CInt(Math.Round(s, MidpointRounding.AwayFromZero)), _
CInt(Math.Round(v, MidpointRounding.AwayFromZero)))
End Function
んだ後にコードをご利用の変換からHSB(うしたHSV)の色のRGBのだが、ここでの私の使用、作業中間値0 1:
Public Function HSVtoRGB(ByVal H As Integer, ByVal S As Integer, ByVal V As Integer) As RGB
''# Scale the Saturation and Value components to be between 0 and 1
Dim hue As Decimal = H
Dim sat As Decimal = S / 100D
Dim val As Decimal = V / 100D
Dim r As Decimal
Dim g As Decimal
Dim b As Decimal
If sat = 0 Then
''# If the saturation is 0, then all colors are the same.
''# (This is some flavor of gray.)
r = val
g = val
b = val
Else
''# Calculate the appropriate sector of a 6-part color wheel
Dim sectorPos As Decimal = hue / 60D
Dim sectorNumber As Integer = CInt(Math.Floor(sectorPos))
''# Get the fractional part of the sector
''# (that is, how many degrees into the sector you are)
Dim fractionalSector As Decimal = sectorPos - sectorNumber
''# Calculate values for the three axes of the color
Dim p As Decimal = val * (1 - sat)
Dim q As Decimal = val * (1 - (sat * fractionalSector))
Dim t As Decimal = val * (1 - (sat * (1 - fractionalSector)))
''# Assign the fractional colors to red, green, and blue
''# components based on the sector the angle is in
Select Case sectorNumber
Case 0, 6
r = val
g = t
b = p
Case 1
r = q
g = val
b = p
Case 2
r = p
g = val
b = t
Case 3
r = p
g = q
b = val
Case 4
r = t
g = p
b = val
Case 5
r = val
g = p
b = q
End Select
End If
''# Scale the red, green, and blue values to be between 0 and 255
r *= 255
g *= 255
b *= 255
''# Return a color in the new color space
Return New RGB(CInt(Math.Round(r, MidpointRounding.AwayFromZero)), _
CInt(Math.Round(g, MidpointRounding.AwayFromZero)), _
CInt(Math.Round(b, MidpointRounding.AwayFromZero)))
End Function
編集: このコードとよく似提供されるものCによるリチャード-ロスIII.私は狩猟の対象として多くの異なるアルゴリズムとしてまた、オンラインrewrote多くのコードは借入金のからしかった広範な試験の精度を検証した。私は怠注者を借りコードから、ただの民間図書館があります。(粉を山にして真ん中をVBバージョンにいる人がないがしたい変換でかなり満足できるパイでした。:-)
他のヒント
それを行う方法に関する私のバージョンは次のとおりです(C、申し訳ありませんが、変換するのは難しくないはずです。 int *
'砂 double *
と out
また ref
ints、およびpointer構文を使用しないでください)
void colorlib_hsbtorgb(double hue, double saturation, double brightness, int *red, int *green, int *blue)
{
if (saturation == 0)
{
*red = *green = *blue = brightness;
}
else
{
// the color wheel consists of 6 sectors. Figure out which sector you're in.
double sectorPos = hue / 60.0;
int sectorNumber = (int)(floor(sectorPos));
// get the fractional part of the sector
double fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color.
double p = brightness * (1.0 - saturation);
double q = brightness * (1.0 - (saturation * fractionalSector));
double t = brightness * (1.0 - (saturation * (1 - fractionalSector)));
// assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber)
{
case 0:
*red = brightness;
*green = t;
*blue = p;
break;
case 1:
*red = q;
*green = brightness;
*blue = p;
break;
case 2:
*red = p;
*green = brightness;
*blue = t;
break;
case 3:
*red = p;
*green = q;
*blue = brightness;
break;
case 4:
*red = t;
*green = p;
*blue = brightness;
break;
case 5:
*red = brightness;
*green = p;
*blue = q;
break;
}
}
}
RGBからHSB:
void colorlib_rgbtohsb(int red, int green, int blue, double *hue, double *saturation, double *brightness)
{
double dRed = red / 255;
double dGreen = green / 255;
double dBlue = blue / 255;
double max = fmax(dRed, fmax(dGreen, dBlue));
double min = fmin(dRed, fmin(dGreen, dBlue));
double h = 0;
if (max == dRed && dGreen >= dBlue)
{
h = 60 * (dGreen - dBlue) / (max - min);
}
else if (max == dRed && dGreen < dBlue)
{
h = 60 * (dGreen - dBlue) / (max - min) + 360;
}
else if (max == dGreen)
{
h = 60 * (dBlue - dRed) / (max - min) + 120;
}
else if (max == dBlue)
{
h = 60 * (dRed - dGreen) / (max - min) + 240;
}
double s = (max == 0) ? 0.0 : (1.0 - (min / max));
*hue = h;
*saturation = s;
*brightness = max;
}
C#でコードを見つけたら、この回答を編集します。
色GetBrightness、Gethue、GetSaturationの方法を使用するのはどうですか?
.NETを使用している場合、なぜ車輪を再発明するのですか?
Dim c = Color.FromArgb(myRed, myGreen, myBlue)
Dim h = c.GetHue()
Dim s = c.GetSaturation()
Dim b = c.GetBrightness()
RGBからHSBへの変換は、 Color
構造:
Function RGBToHSB(rgb As RGBColor) As HSBColor
Dim c As Color = Color.FromArgb(rgb.Red, rgb.Green, rgb.Blue)
RGBToHSB.Hue = c.GetHue()
RGBToHSB.Saturation = c.GetSaturation()
RGBToHSB.Brightness = c.GetBrightness()
End Function
ただし、逆はサポートしていません。
解決
r、g、bの最大であるため、輝度コンポーネントを非常に簡単に計算できます(参照:式の式 ロチェスター工科大学からRGBからHSVへ)。 255で割ってスケールを掛けることで、縮小することができます。これは、既存のコードで行われたものと同じです。
maxRGB = Max(Max(rgb.Red, rgb.Green), rgb.Blue)
b = maxRGB
...
RGBToHSB.Brightness = b * 100 / 255
したがって、最終的には、組み込みの.NET関数を使用して、明るさを計算することができます。完全なコードは(タイプを除く)になります:
Function RGBToHSB(rgb As RGBColor) As HSBColor
Dim maxRGB As Double
maxRGB = Max(Max(rgb.Red, rgb.Green), rgb.Blue)
Dim c As Color = Color.FromArgb(rgb.Red, rgb.Green, rgb.Blue)
RGBToHSB.Hue = c.GetHue()
RGBToHSB.Saturation = c.GetSaturation() * 100
RGBToHSB.Brightness = maxRGB * 100 / 255
End Function
HSB(HSVと同じ)について少し
から ダレル・レックス・フィンリー:
HSV(HSBとも呼ばれる)システムでは、色の明るさはVコンポーネントです。そのコンポーネントは、色の3つのRGBコンポーネントのいずれかの最大値として単純に定義されます。Vを決定すると、他の2つのRGBコンポーネントは無視されます。
によると Microsoftドキュメント にとって Color.GetBrightness
:
色合いの飽和度を取得します(HSB)この色構造の輝度値。
私は、MSDNがHSLのようなことを意味するときにHSBを使用するといういくつかの参照を見つけました これはMSDNブログからです (コメントを参照)。簡単なテストでは、これが真であることがわかります(C#):
// Define a color which gives different HSL and HSB value
Color c = Color.FromArgb(255, 0, 0);
// Get the brightness, scale it from 0.0 - 1.0 up to 0 - 255
int bright = (int)(c.GetBrightness() * 255.00);
// Output it
Console.WriteLine(bright.ToString());
これにより、値が表示されます 127
, 、これは明らかにHSLです。 HSBの場合、値はRGとBの最大である必要があります(つまり 255
).