如何在RGB图像中将红色与蓝色交换并保持亮度?
问题描述:
我读一个24位的位图:如何在RGB图像中将红色与蓝色交换并保持亮度?
var P: PByteArray;
...
for y:=0 to Bmp.Height-1 do begin
P := Bmp.ScanLine[y];
for x:=0 to Bmp.Width-1 do begin
R := P[3*x+2];
G := P[3*x+1];
B := P[3*x ];
现在我换RGB与BGR:
P[3*x+2] := B;
P[3*x+1] := G;
P[3*x ] := R;
所以,如果我有红色的东西我的形象在它现在的蓝色,什么是蓝色的是红色的。但问题在于亮度变化,新图像要么是来源图像较暗或较亮。 如何使输出图像与输入图像一样明亮/黑暗?
答
我建议你先从RGB转换为HSL。
然后打开colorwheel(又名Hue,见下文)将红色转换为蓝色并转换回RGB。
这应该保持亮度。
德尔福有一个单位,只是:VCL.GraphUtil
。
您可以使用:procedure ColorRGBToHLS(clrRGB: TColorRef; var Hue, Luminance, Saturation: Word);
和function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef;
。
色相
色调是合理言自明的,并且在0开始用于红色。随着价值的增加,它会穿过彩虹的颜色。我还没有测试GraphUtils输出什么,但如果一个圆圈有256度的值是:
- 红0
- 橙20
- 黄40
- 格林80
- 青色120
- 蓝色160
- 紫色180
- 洋红色200
- 粉红220
这是无益的是Embarcadero公司使用非标准HLS
代替HSL
,但这就是生活。
转换为线性,用亮度函数进行加权:https://en.wikipedia.org/wiki/Relative_luminance –
@J ...所以我应该计算旧的亮度,新的亮度,然后除以新/旧把我的新B和新R乘以这个值? – Tom
是的,新亮度=旧亮度,但交换亮度函数中的R/B权重,而不是RGB值。 –