Una pregunta bastante popular es ¿cómo obtener un acceso rápido a los píxeles TBITMAP ?
Es fácil de hacer en Delphi , con la propiedad de escaneo [] , debido al número limitado de formatos de píxeles, pero bastante difícil en Lázaro .
Por ejemplo: https://wiki.freepascal.org/fast_direct_pixel_access
Propongo un módulo pequeño, módulo "bitMappixels.pas" que simplifica el trabajo para llamar a tbitmapdata.map () y tbitmapData.unmap () .
Obtiene una matriz de píxeles de $ AarrgGBB en la propiedad de datos , y abilibia establece y obtiene color de píxeles usando setPixel ()/getPixel () .
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec; // for easy access to the channels
begin
// Reading the colors of the image into map "Data", width mode "ReadWrite", in the "False" alpha channel mode.
// The alpha channel will be set to 0 on every element of the array. ($00RRGGBB, $00RRGGBB, ...)
Data.Map(Bitmap, TAccessMode.ReadWrite, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
// Read color at (X, Y) to Pixel record
Pixel := Data.GetPixel(X, Y);
// some changes of Pixel
Pixel.R := (Pixel.R + Pixel.G + Pixel.B) div 3 ;
Pixel.G := Pixel.R;
Pixel.B := Pixel.R;
// ...
// Write Pixel record to (X, Y) in map
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
// Writing the map to the image.
// Since we have abandoned Alpha, the pixel format will be set to pf24bit.
Data.Unmap();
end ;
end ;Características clave:

procedure InvertColors ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, False); // RGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.R := 255 - Pixel.R;
Pixel.G := 255 - Pixel.G;
Pixel.B := 255 - Pixel.B;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
procedure HalfAlpha ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, True); // ARGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.A := Pixel.A div 2 ;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
function MakePlasm (): TBitmap;
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize( 300 , 300 );
Data.Map(Result, TAccessMode.Write, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel.R := Byte(Trunc(
100 + 100 * (Sin(X * Cos(Y * 0.049 ) * 0.01 ) + Cos(X * 0.0123 - Y * 0.09 ))));
Pixel.G := 0 ;
Pixel.B := Byte(Trunc(
Pixel.R + 100 * (Sin(X * Cos(X * 0.039 ) * 0.022 ) + Sin(X * 0.01 - Y * 0.029 ))));
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ;
function Mix ( const A, B: TBitmap): TBitmap;
function Min (A, B: Integer): Integer;
begin
if A < B then Exit(A) else Exit(B);
end ;
var
DataA, DataB, DataResult: TBitmapData;
X, Y: Integer;
PixelA, PixelB, PixelResult: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize(Min(A.Width, B.Width), Min(A.Height, B.Height));
// this needed for correct Unmap() on exception
DataA.Init();
DataB.Init();
DataResult.Init();
try
DataA.Map(A, TAccessMode.Read, False);
DataB.Map(B, TAccessMode.Read, False);
DataResult.Map(Result, TAccessMode.Write, False);
for Y := 0 to DataResult.Height - 1 do
begin
for X := 0 to DataResult.Width - 1 do
begin
PixelA := DataA.Pixels[X, Y];
PixelB := DataB.Pixels[X, Y];
PixelResult.R := (PixelA.R + PixelB.R) div 2 ;
PixelResult.G := (PixelA.G + PixelB.G) div 2 ;
PixelResult.B := (PixelA.B + PixelB.B) div 2 ;
DataResult[X, Y] := PixelResult;
end ;
end ;
finally
DataA.Unmap();
DataB.Unmap();
DataResult.Unmap();
end ;
end ; Есть довольно попу ", в собществе lázarus разработчиков, represente: как полчить ыстрый досeche .
Это л лко сделать в delphi ба боonculo свойству escane довольно сightжно jero Lazarus .
Приеры сложностей, которые могт возникнуть: https://wiki.freepascal.org/fast_direct_pixel_access.
Í предлаг неболшой , в– виде о Saz TbitmapData.unmap () .
Вы полчаете масив пиксе ideaй в форomine $ aarrggbbb в свойстве datos , а также возннож momento поеenoщю setPixel ()/getPixel () .
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec; // for easy access to the channels
begin
// Reading the colors of the image into map "Data", width mode "ReadWrite", in the "False" alpha channel mode.
// The alpha channel will be set to 0 on every element of the array. ($00RRGGBB, $00RRGGBB, ...)
Data.Map(Bitmap, TAccessMode.ReadWrite, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
// Read color at (X, Y) to Pixel record
Pixel := Data.GetPixel(X, Y);
// some changes of Pixel
Pixel.R := (Pixel.R + Pixel.G + Pixel.B) div 3 ;
Pixel.G := Pixel.R;
Pixel.B := Pixel.R;
// ...
// Write Pixel record to (X, Y) in map
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
// Writing the map to the image.
// Since we have abandoned Alpha, the pixel format will be set to pf24bit.
Data.Unmap();
end ;
end ;Онновные фичи:

procedure InvertColors ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, False); // RGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.R := 255 - Pixel.R;
Pixel.G := 255 - Pixel.G;
Pixel.B := 255 - Pixel.B;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
procedure HalfAlpha ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, True); // ARGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.A := Pixel.A div 2 ;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
function MakePlasm (): TBitmap;
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize( 300 , 300 );
Data.Map(Result, TAccessMode.Write, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel.R := Byte(Trunc(
100 + 100 * (Sin(X * Cos(Y * 0.049 ) * 0.01 ) + Cos(X * 0.0123 - Y * 0.09 ))));
Pixel.G := 0 ;
Pixel.B := Byte(Trunc(
Pixel.R + 100 * (Sin(X * Cos(X * 0.039 ) * 0.022 ) + Sin(X * 0.01 - Y * 0.029 ))));
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ;
function Mix ( const A, B: TBitmap): TBitmap;
function Min (A, B: Integer): Integer;
begin
if A < B then Exit(A) else Exit(B);
end ;
var
DataA, DataB, DataResult: TBitmapData;
X, Y: Integer;
PixelA, PixelB, PixelResult: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize(Min(A.Width, B.Width), Min(A.Height, B.Height));
// this needed for correct Unmap() on exception
DataA.Init();
DataB.Init();
DataResult.Init();
try
DataA.Map(A, TAccessMode.Read, False);
DataB.Map(B, TAccessMode.Read, False);
DataResult.Map(Result, TAccessMode.Write, False);
for Y := 0 to DataResult.Height - 1 do
begin
for X := 0 to DataResult.Width - 1 do
begin
PixelA := DataA.Pixels[X, Y];
PixelB := DataB.Pixels[X, Y];
PixelResult.R := (PixelA.R + PixelB.R) div 2 ;
PixelResult.G := (PixelA.G + PixelB.G) div 2 ;
PixelResult.B := (PixelA.B + PixelB.B) div 2 ;
DataResult[X, Y] := PixelResult;
end ;
end ;
finally
DataA.Unmap();
DataB.Unmap();
DataResult.Unmap();
end ;
end ; Є досить популлне, у с sea лнот і Lazarus розробникorme, питанннiego: як отимículos шви S
Це л гко зроonc. складно в lazarus .
Приклади склаlear
Я проalo TbitmapData.unmap () .
Ви отриominzєе м. за допоomineгю setPixel ()/getPixel () .
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec; // for easy access to the channels
begin
// Reading the colors of the image into map "Data", width mode "ReadWrite", in the "False" alpha channel mode.
// The alpha channel will be set to 0 on every element of the array. ($00RRGGBB, $00RRGGBB, ...)
Data.Map(Bitmap, TAccessMode.ReadWrite, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
// Read color at (X, Y) to Pixel record
Pixel := Data.GetPixel(X, Y);
// some changes of Pixel
Pixel.R := (Pixel.R + Pixel.G + Pixel.B) div 3 ;
Pixel.G := Pixel.R;
Pixel.B := Pixel.R;
// ...
// Write Pixel record to (X, Y) in map
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
// Writing the map to the image.
// Since we have abandoned Alpha, the pixel format will be set to pf24bit.
Data.Unmap();
end ;
end ;Он ф ф ф ф ф.

procedure InvertColors ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, False); // RGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.R := 255 - Pixel.R;
Pixel.G := 255 - Pixel.G;
Pixel.B := 255 - Pixel.B;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
procedure HalfAlpha ( const Bitmap: TBitmap);
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Data.Map(Bitmap, TAccessMode.ReadWrite, True); // ARGB access
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel := Data.GetPixel(X, Y);
Pixel.A := Pixel.A div 2 ;
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ; 
function MakePlasm (): TBitmap;
var
Data: TBitmapData;
X, Y: Integer;
Pixel: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize( 300 , 300 );
Data.Map(Result, TAccessMode.Write, False);
try
for Y := 0 to Data.Height - 1 do
begin
for X := 0 to Data.Width - 1 do
begin
Pixel.R := Byte(Trunc(
100 + 100 * (Sin(X * Cos(Y * 0.049 ) * 0.01 ) + Cos(X * 0.0123 - Y * 0.09 ))));
Pixel.G := 0 ;
Pixel.B := Byte(Trunc(
Pixel.R + 100 * (Sin(X * Cos(X * 0.039 ) * 0.022 ) + Sin(X * 0.01 - Y * 0.029 ))));
Data.SetPixel(X, Y, Pixel);
end ;
end ;
finally
Data.Unmap();
end ;
end ;
function Mix ( const A, B: TBitmap): TBitmap;
function Min (A, B: Integer): Integer;
begin
if A < B then Exit(A) else Exit(B);
end ;
var
DataA, DataB, DataResult: TBitmapData;
X, Y: Integer;
PixelA, PixelB, PixelResult: TPixelRec;
begin
Result := TBitmap.Create();
Result.SetSize(Min(A.Width, B.Width), Min(A.Height, B.Height));
// this needed for correct Unmap() on exception
DataA.Init();
DataB.Init();
DataResult.Init();
try
DataA.Map(A, TAccessMode.Read, False);
DataB.Map(B, TAccessMode.Read, False);
DataResult.Map(Result, TAccessMode.Write, False);
for Y := 0 to DataResult.Height - 1 do
begin
for X := 0 to DataResult.Width - 1 do
begin
PixelA := DataA.Pixels[X, Y];
PixelB := DataB.Pixels[X, Y];
PixelResult.R := (PixelA.R + PixelB.R) div 2 ;
PixelResult.G := (PixelA.G + PixelB.G) div 2 ;
PixelResult.B := (PixelA.B + PixelB.B) div 2 ;
DataResult[X, Y] := PixelResult;
end ;
end ;
finally
DataA.Unmap();
DataB.Unmap();
DataResult.Unmap();
end ;
end ;