¿Cómo se puede acceder de forma rápida a los píxeles de un TBitmap?
El acceso a los píxeles de un TCanvas a través de su propiedad Pixels deja mucho que desear en cuanto a velocidad se refiere. Una forma más rápida es acceder es a través de la propiedad ScanLine del objeto TBitmap.
Probad este ejemplo. Para ello, situad en un formulario un TImage y tres TScrollBar.
Cargad en el TImage un bitmap de 24 bits (cualquier foto en true color que tengais).
Copiad el siguiente programa "encima" del vuestro y probadlo:
Código Delphi
[-]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
ScrollBar1: TScrollBar;
ScrollBar2: TScrollBar;
ScrollBar3: TScrollBar;
procedure FormCreate(Sender: TObject);
public
procedure ScrollChange(Sender: TObject);
procedure SetColor(AColor: Integer; ACanal: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
ScrollBar1.Max:= 255;
ScrollBar1.Position:= 128;
ScrollBar1.LargeChange:= 16;
ScrollBar1.Tag:= 2;
ScrollBar1.OnChange:= ScrollChange;
ScrollBar2.Max:= 255;
ScrollBar2.Position:= 128;
ScrollBar2.LargeChange:= 16;
ScrollBar2.Tag:= 1;
ScrollBar2.OnChange:= ScrollChange;
ScrollBar3.Max:= 255;
ScrollBar3.Position:= 128;
ScrollBar3.LargeChange:= 16;
ScrollBar3.Tag:= 0;
ScrollBar3.OnChange:= ScrollChange;
end;
procedure TForm1.SetColor(AColor: Integer; ACanal: Integer);
var
i, x, y: integer;
P : PByteArray;
begin
with Image1.Picture.Bitmap do begin
for y:= 0 to Height-1 do begin
P:= ScanLine[y];
x:= Width*(2-ACanal);
for i:= 0 to (Width-1) div 3 do begin
P[x + ACanal]:= AColor;
Inc(x, 3);
end;
end;
end;
Image1.Refresh;
end;
procedure TForm1.ScrollChange(Sender: TObject);
begin
if Sender is TScrollBar then
SetColor(TScrollBar(Sender).Position, TScrollBar(Sender).Tag);
end;
end.