编程交换颜色从装载位图红色,绿色,蓝色或灰色,逐像素

问题描述:

下载源$ C ​​$ C在这里: http://www.eyeClaxton.com/下载/德尔福/ ColorSwap.zip

Download source code here: http://www.eyeClaxton.com/download/delphi/ColorSwap.zip

是的,我要的东西大多是蓝色的东西大多是绿色的转换。

Yes, I want to convert something "mostly blue" to something "mostly green".

我想取原始位(浅蓝色),改变颜色(逐像素)的红色,绿色,蓝色和灰色的等价关系。为了得到我的意思的想法,我已经包括源$ C ​​$ c和屏幕截图。任何帮助将大大AP preciated。如果需要了解更多信息,请随时提出。

I would like to take a original bitmap (light blue) and change the colors (Pixel by Pixel) to the red, green, blue and gray equivalence relation. To get an idea of what I mean, I have include the source code and a screen shot. Any help would be greatly appreciated. If more information is needed, please feel free to ask.

如果你可以看看下面的code,我有我要找的帮助三种功能。功能RGBToRed,RGBToGreen和RGBToRed我似乎无法拿出合适的公式。

If you could take a look at the code below, I have three functions that I'm looking for help on. The functions "RGBToRed, RGBToGreen and RGBToRed" I can't seem to come up with the right formulas.

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TMainFrm = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Panel2: TPanel;
    Label2: TLabel;
    Button1: TButton;
    BeforeImage1: TImage;
    AfterImage1: TImage;
    RadioGroup1: TRadioGroup;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.DFM}
function RGBToGray(RGBColor: TColor): TColor;
var
  Gray: Byte;
begin
  Gray := Round(
    (0.90 * GetRValue(RGBColor)) +
    (0.88 * GetGValue(RGBColor)) +
    (0.33 * GetBValue(RGBColor)));

  Result := RGB(Gray, Gray, Gray);
end;

function RGBToRed(RGBColor: TColor): TColor;
var
  Red: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Red, Red, Red);
end;

function RGBToGreen(RGBColor: TColor): TColor;
var
  Green: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Green, Green, Green);
end;

function RGBToBlue(RGBColor: TColor): TColor;
var
  Blue: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Blue, Blue, Blue);
end;

procedure TMainFrm.FormCreate(Sender: TObject);
begin
  BeforeImage1.Picture.LoadFromFile('Images\RightCenter.bmp');
end;

procedure TMainFrm.Button1Click(Sender: TObject);
var
  Bitmap: TBitmap;
  I, X: Integer;
  Color: Integer;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.LoadFromFile('Images\RightCenter.bmp');

    for X := 0 to Bitmap.Height do
    begin
      for I := 0 to Bitmap.Width do
      begin
        Color := ColorToRGB(Bitmap.Canvas.Pixels[I, X]);

        case Color of
          $00000000: ;   // Skip any Color Here!
        else
          case RadioGroup1.ItemIndex of
            0: Bitmap.Canvas.Pixels[I, X] := RGBToBlue(Color);
            1: Bitmap.Canvas.Pixels[I, X] := RGBToRed(Color);
            2: Bitmap.Canvas.Pixels[I, X] := RGBToGreen(Color);
            3: Bitmap.Canvas.Pixels[I, X] := RGBToGray(Color);
          end;
        end;
      end;
    end;
    AfterImage1.Picture.Graphic := Bitmap;
  finally
    Bitmap.Free;
  end;
end;

end.

好吧,我不作出更清晰道歉。我试图把一个位图(蓝色颜色),并用另一种颜色更换为蓝色像素。像下面的截图。

Okay, I apologize for not making it clearer. I'm trying to take a bitmap (blue in color) and swap the blue pixels with another color. Like the shots below.

我不知道你要实现的目标。首先,什么是问题与等价关系办?

I have no idea what you are trying to achieve. First, what does the question have to do with equivalence relations?

其次,code

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蓝色。在上面的code,然而,红色未初始化,所以结果可以是任何灰色(视什么红色恰好是)。 [而且,正如你可能知道,如果你混合红,绿,蓝等量的,因为你这样做,你会得到灰色。]例如,红色可能发生45一次运行该应用程序,然后将结果将是灰色 RGB(45,45,45)。下一次,它可能是163。

is meaningless. The return value is undefined. The RGB functions takes red, green, and blue intensities in the range 0 to 255 and returns the TColor having these components. For instance, RGB(255, 0, 0) is pure red, that is, 255 red, 0 green, and 0 blue. In the code above, however, Red is not initialized, so Result can be any grey colour (depending on what Red happens to be). [And, as you probably know, if you mix equal amounts of red, green, and blue, as you do, you get grey.] For instance, Red might happen to be 45 one time you run the application, and then the result will be the grey colour RGB(45, 45, 45). Next time it might be 163.

也许你想接受一个 TColor ,并返回它的红色成分功能?然后 GetRValue 会做的, - 当然 - 也有 GetGValue GetBValue

Maybe you want a function that accepts a TColor and returns the red component of it? Then GetRValue will do, and - of course - there is also GetGValue and GetBValue.

或者,也许你想从一个给定的 TColor 创建一个灰色的颜色,当您使用Photoshop从彩色图像创建一个灰度图像做。然后,如果颜色 TColor ,适当的灰度值为

Or, maybe you want to create a grey colour from a given TColor, as you do when you use Photoshop to create a greyscale image from a colour image. Then, if Color is the TColor, the appropriate grey value is

grey := (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) div 3;

有这样做的其他的方式(造成微妙的不同灰度的图像,但是这是最简单的(和最快))。 (例如,您可以将颜色从RGB转换为HSV或HSL,然后设置饱和度为零。)

There are other ways of doing this (resulting in subtly different greyscale images, but this is the easiest (and fastest)). (For instance, you can convert the colour from RGB to HSV or HSL and then set the saturation equal to zero.)

更新

我想我看到你想要做什么。也许你要提取的红色,绿色和蓝色通道。也就是说,要变换每个像素 RGB(R,G,B) RGB(R,0,0)在红色的情况下。如果这是你想做的事,那么你应该做的。

I think I see what you want to do. Maybe you want to extract the red, green, and blue channels. That is, you want to transform each pixel RGB(R, G, B) to RGB(R, 0, 0) in the red case. If this is what you want to do, then you should do

function RGBToRed(RGBColor: TColor): TColor;
begin
  Result := RGB(GetRValue(RGBColor), 0, 0);
end;

和类似的其它部件,也就是

and similarly for the other components, that is

function RGBToGreen(RGBColor: TColor): TColor;
begin
  Result := RGB(0, GetGValue(RGBColor), 0);
end;

function RGBToBlue(RGBColor: TColor): TColor;
begin
  Result := RGB(0, 0, GetBValue(RGBColor));
end;

或者,也许

或者,也许你只是想使图像灰度,然后在颜色是红色(或绿色或蓝色)。然后,你需要的重型机械。从理论上讲,您希望从替换每个像素HSV(H,S,V) HSV(0,S,V)在红色的情况下, HSV(120,S,v)在绿色的情况下,和 HSV(240,S,v)中的蓝色外壳。或者,也许你还希望饱和取值设置为1。

Or maybe you just want to make the image greyscale, and then "colour" it red (or green, or blue). Then you need the heavy machinery. Theoretically, you wish to replace each pixel from HSV(h, s, v) to HSV(0, s, v) in the red case, HSV(120, s, v) in the green case, and HSV(240, s, v) in the blue case. Or, maybe you also wish to set the saturation s to 1.

我用下面的rutines到RGB和HSV之间的转换:

I use the following rutines to convert between RGB and 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;

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;

其中,

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;

最终的结果,在绿色的情况下,会像

The end result, in the green case, will be like

在第一种情况下(色相固定至120)和

in the first case (hue fixed to 120) and

在后一种情况下(色相固定至120,饱和度固定为1)。

in the latter case (hue fixed to 120, saturation fixed to 1).

或可能

您的问题很vauge,甚至与编辑。你想要的东西大多是蓝色的东西大多是绿色转变。但也有这样做的一千种方式!一个非常简单的方法,当然,只是换了蓝色和绿色通道,即,将 RGB(R,G,B) RGB(R,G,b),或明确,

Your question is very vauge, even with the edit. You want to convert something "mostly blue" to something "mostly green". But there are a thousand ways of doing that! A very simple way, of course, is just to swap the blue and green channels, that is, replace RGB(r, g, b) with RGB(r, b, g), or, explicitly,

function SwapBlueGreen(Color: TColor): TColor;
begin
  result := RGB(GetRValue(Color), GetBValue(Color), GetGValue(Color));
end;

然后你喜欢的东西。

Then you get something like

,其中红色和绿色通道已被调换。请注意,红杖现在是绿色,绿色的草地现在是红色的。什么是白依然白色的。

where the red and green channels have been swapped. Notice that the red stick is now green, and the green grass is now red. What's white remains white.

最后

欢迎来操纵像素图的世界!有很多的方便和乐趣的事情要做。一些我的例子:http://english.rejbrand.se/algosim/manual/pmproc/pmproc.html

Welcome to the world of pixmap manipulation! There is a lot of easy and fun things to do. Some more of my examples: http://english.rejbrand.se/algosim/manual/pmproc/pmproc.html