Download the source code with compiled executable here (Size: 161 KB (165,230 bytes)): http://www.eyeClaxton.com/download/delphi/ColorSwap.zip
Original bitmap size is just 28x15 pixels, and the color is light blue. I would like to be able to click on any of the colored panels to the right and change the original bitmap color from light blue to the color of the panel.
If you click on the gray panel you can see this in action, I just can't figure out how to do this correctly with the other colors. Any help would be greatly appreciated. If more information is needed, please feel free to ask.
I have asked this question before but I was unable to make clear what I was trying to do, so I hope this one is a little bit more clear.
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classe开发者_高级运维s, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TMainFrm = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Panel2: TPanel;
Label2: TLabel;
BeforeImage1: TImage;
AfterImage1: TImage;
Panel3: TPanel;
Panel4: TPanel;
Panel5: TPanel;
Panel6: TPanel;
Panel7: TPanel;
Panel8: TPanel;
Panel9: TPanel;
Image1: TImage;
Label3: TLabel;
Panel10: TPanel;
Memo1: TMemo;
Label4: TLabel;
procedure FormCreate(Sender: TObject);
procedure Panel4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainFrm: TMainFrm;
implementation
uses
Math;
{$R *.DFM}
function Min(const A, B, C: Integer): Integer;
begin
Result := Math.Min(A, Math.Min(B, C));
end;
function Max(const A, B, C: Integer): Integer;
begin
Result := Math.Max(A, Math.Max(B, C));
end;
function RGBToGray(theRed, theGreen, theBlue: Byte): Byte;
begin
Result := (Max(theRed, theGreen, theBlue) + Min(theRed, theGreen, theBlue)) div 2;
end;
function BlueToGray(theColor: TColor): TColor;
var
R, G, B, X: Byte;
begin
R := (theColor and $FF);
G := (theColor and $FF00) shr 8;
B := (theColor and $FF0000) shr 16;
X := RGBToGray(R, G, B);
Result := TColor(RGB(X, X, X));
end;
procedure TMainFrm.FormCreate(Sender: TObject);
begin
Image1.Picture.Graphic := BeforeImage1.Picture.Bitmap;
end;
procedure TMainFrm.Panel4Click(Sender: TObject);
var
Bitmap: TBitmap;
I, X: Integer;
Color: Integer;
begin
Bitmap := TBitmap.Create;
try
Bitmap.Assign(BeforeImage1.Picture.Bitmap);
Panel4.Caption := '';
Panel5.Caption := '';
Panel6.Caption := '';
Panel7.Caption := '';
Panel8.Caption := '';
Panel9.Caption := '';
(Sender as TPanel).Caption := 'X';
for X := 0 to (Bitmap.Height - 1) do
begin
for I := 0 to (Bitmap.Width - 1) do
begin
Color := Bitmap.Canvas.Pixels[I, X];
case (Sender as TPanel).Tag of
1: ; // I need a function something like BlueToRed(Color);
2: ; // I need a function something like BlueToGreen(Color);
3: ; // I need a function something like BlueToYellow(Color);
4: ; // I need a function something like BlueToFuchsia(Color);
5: ; // I need a function something like BlueToCyan(Color);
6: Bitmap.Canvas.Pixels[I, X] := BlueToGray(Color);
end;
Image1.Picture.Graphic := Bitmap;
end;
Application.ProcessMessages();
Sleep(100);
end;
AfterImage1.Picture.Graphic := Bitmap;
finally
Bitmap.Free;
end;
end;
end.
The question is still not well-defined, because grey doesn't work like any other colour (neither in the RGB model, nor in the HSV model), so there is no single, obvious way to implement the other colour buttons.
However, one natural way (maybe the most natural way) is to do as I suggested in my answer to the previous question, namely to convert 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. The numbers 0, 120, and 240 are the angles of the hue.
To do this, you need only functions to convert between RGB and HSV (and I did give you those in the last question).
I see in your code that you have named the functions BlueToRed(Color)
etc., which is inappropriate, because any colour will become red etc., so better names would be ColorToRed
etc.
To make this as clear as possible, I have added the code for the red and green buttons in your program. See the updated version at
http://privat.rejbrand.se/ColorSwap.zip
(Also, please notice that "ColorSwap" is an inappropriate name. A better name would be "FixHue".)
Performance
Also, as you might have noticed, performance is terrible! It takes several seconds to colour the image!
This is not because the CPU is slow (indeed, it is extermely fast), but due to mainly two design bugs:
Never update a pixmap on-screen. Instead, update the pixmap in memory, and then, when done, copy the bitmap to screen.
Don't use the
Pixels
property. This is awkwardly slow. Use theScanline
instead.
You should be able to do a few hundred updates per second if you do it right...
精彩评论