如何在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; 

所以,如果我有红色的东西我的形象在它现在的蓝色,什么是蓝色的是红色的。但问题在于亮度变化,新图像要么是来源图像较暗或较亮。 如何使输出图像与输入图像一样明亮/黑暗?

+2

转换为线性,用亮度函数进行加权:https://en.wikipedia.org/wiki/Relative_luminance –

+0

@J ...所以我应该计算旧的亮度,新的亮度,然后除以新/旧把我的新B和新R乘以这个值? – Tom

+0

是的,新亮度=旧亮度,但交换亮度函数中的R/B权重,而不是RGB值。 –

我建议你先从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,但这就是生活。

+0

谢谢,我尝试了这种方法,并得到了一个蓝色的图像,但它不像源红色一样明亮:http://pastebin.com/zG2PgFFU – Tom

+1

也许检查上述功能的细节,并使用亮度维基数据来调整它们? – Johan