我不知道你想实现什么目标。首先,这个问题与什么有关系等价关系 https://en.wikipedia.org/wiki/Equivalence_relation?
其次,代码
function RGBToRed(RGBColor: TColor): TColor;
var
Red: Byte;
begin
// Not sure of the algorithm for this color
Result := RGB(Red, Red, Red);
end;
毫无意义。返回值未定义。这RGB
函数采用 0 到 255 范围内的红色、绿色和蓝色强度,并返回TColor
拥有这些组件。例如,RGB(255, 0, 0)
是纯红色,即255红、0绿、0蓝。然而,在上面的代码中,Red
没有初始化,所以Result
可以是任何灰色(取决于什么Red
恰好是)。 [而且,正如您可能知道的那样,如果您将等量的红色、绿色和蓝色混合在一起,就会得到灰色。] 例如,Red
当你运行应用程序时,可能碰巧是 45,然后结果将是灰色RGB(45, 45, 45)
。下次可能是163。
也许你想要一个接受a的函数TColor
并返回它的红色分量?然后GetRValue
会做的,而且 - 当然 - 还有GetGValue
and GetBValue
.
或者,也许您想从给定的颜色创建灰色TColor
,就像使用 Photoshop 从彩色图像创建灰度图像时所做的那样。那么,如果Color
is the TColor
,合适的灰度值为
grey := (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) div 3;
还有其他方法可以做到这一点(导致灰度图像略有不同,但这是最简单(也是最快)的)。 (例如,您可以将颜色从 RGB 转换为 HSV 或 HSL,然后将饱和度设置为零。)
Update
我想我明白你想做什么。也许您想提取红色、绿色和蓝色通道。也就是说,你想要变换每个像素RGB(R, G, B)
to RGB(R, 0, 0)
在红色的情况下。如果这是你想做的,那么你应该这样做
function RGBToRed(RGBColor: TColor): TColor;
begin
Result := RGB(GetRValue(RGBColor), 0, 0);
end;
对于其他组件也类似,即
function RGBToGreen(RGBColor: TColor): TColor;
begin
Result := RGB(0, GetGValue(RGBColor), 0);
end;
and
function RGBToBlue(RGBColor: TColor): TColor;
begin
Result := RGB(0, 0, GetBValue(RGBColor));
end;
或者可能
或者您可能只想将图像设为灰度,然后将其“着色”为红色(或绿色或蓝色)。那么你需要重型机械。理论上,您希望替换其中的每个像素HSV(h, s, v)
to HSV(0, s, v)
在红色的情况下,HSV(120, s, v)
在绿色的情况下,并且HSV(240, s, v)
在蓝色的情况下。或者,也许您还希望设置饱和度s
to 1.
我使用以下程序在 RGB 和 HSV 之间进行转换:
function RGBToHSV(const Color: TRGB): THSV;
var
cmax, cmin, cdiff: real;
begin
cmax := MaxComponent(Color);
cmin := MinComponent(Color);
cdiff := cmax - cmin;
with Color, result do
begin
// Hue
if cmax = cmin then
hsvHue := 0
else if cmax = rgbRed then
hsvHue := (60 * (rgbGreen - rgbBlue) / cdiff)
else if cmax = rgbGreen then
hsvHue := (60 * (rgbBlue - rgbRed) / cdiff) + 120
else
hsvHue := (60 * (rgbRed - rgbGreen) / cdiff) + 240;
hsvHue := Fix360(hsvHue);
// Saturation
if cmax = 0 then
hsvSaturation := 0
else
hsvSaturation := 1 - cmin / cmax;
// Value
hsvValue := cmax;
end;
end;
and
function HSVToRGB(const Color: THSV): TRGB;
var
hi: integer;
f, q, p, t: real;
begin
with Color do
begin
hi := floor(hsvHue / 60) mod 6;
f := hsvHue / 60 - floor(hsvHue / 60);
p := hsvValue * (1 - hsvSaturation);
q := hsvValue * (1 - f * hsvSaturation);
t := hsvValue * (1 - (1 - f) * hsvSaturation);
case hi of
0: result := RGB(hsvValue, t, p);
1: result := RGB(q, hsvValue, p);
2: result := RGB(p, hsvValue, t);
3: result := RGB(p, q, hsvValue);
4: result := RGB(t, p, hsvValue);
5: result := RGB(hsvValue, p, q);
end;
end;
end;
where
type
TRGB = record
rgbRed, // red intensity between 0 and 1
rgbGreen, // green intensity between 0 and 1
rgbBlue: double; // blue intensity between 0 and 1
end;
THSV = record
hsvHue, // hue angle between 0 and 360
hsvSaturation, // saturation between 0 (grey) and 1 (full colour)
hsvValue: double; // value between 0 (dark) and 1 ("normal")
end;
在绿色的情况下,最终结果将是这样的
在第一种情况下(色调固定为 120)并且
在后一种情况下(色调固定为 120,饱和度固定为 1)。
或者,可能
即使经过编辑,你的问题也很模糊。您想要将“主要是蓝色”的内容转换为“主要是绿色”的内容。但有一千种方法可以做到这一点!当然,一个很简单的方法就是将蓝绿通道互换,即替换RGB(r, g, b)
with RGB(r, b, g)
,或者明确地,
function SwapBlueGreen(Color: TColor): TColor;
begin
result := RGB(GetRValue(Color), GetBValue(Color), GetGValue(Color));
end;
然后你会得到类似的东西
红色和绿色通道已交换。请注意,红棍现在是绿色的,绿草现在是红色的。白色的东西仍然是白色的。
Finally
欢迎来到像素图操作的世界!有很多简单而有趣的事情可以做。我的更多例子:https://english.rejbrand.se/algosim/manual/pmproc/pmproc.html https://english.rejbrand.se/algosim/manual/pmproc/pmproc.html