I'm using a lot of procedures for processing bitmaps and
PNG that uses
ScanLine. But I have declared custom types to represents
BGR pixels. I'm using my code for
Windows only and it works excellent.
Additional types:
type
TRGBTriple = packed record
B, G, R: UInt8;
end;
type
PRGBTripleArr = ^TRGBTripleArr;
TRGBTripleArr = packed array [0 .. MaxInt div SizeOf(TRGBTriple) - 1] of TRGBTriple;
Sample procedure to process 24-bit bitmap below. This procedure is used to dim (darken) the bitmap:
procedure DimBitmap(ABitmap: TBitmap; ALevel: UInt8);
var
Line: PRGBTripleArr;
LineIndex, PixelIndex: Integer;
begin
ABitmap.BeginUpdate();
ALevel := 255 - ALevel;
for LineIndex := 0 to ABitmap.Height - 1 do
begin
Line := ABitmap.ScanLine[LineIndex];
for PixelIndex := 0 to ABitmap.Width - 1 do
with Line^[PixelIndex] do
begin
B := B * ALevel shr 8;
G := G * ALevel shr 8;
R := R * ALevel shr 8;
end;
end;
ABitmap.EndUpdate();
end;
I'm using this procedure in my
Deep Platformer semi-game, witch is not public yet. But when I finish this project, I will publish its sources.
Second example is a procedure, that rotates the source
PNG:
procedure RotatePNGCounterClockwise(AGraphic: TPortableNetworkGraphic);
var
Source: TPortableNetworkGraphic;
SourceLine, GraphicLine: PRGBTripleArr;
LineIndex, PixelIndex: Integer;
begin
Source := TPortableNetworkGraphic.Create();
try
Source.Assign(AGraphic);
Source.BeginUpdate();
AGraphic.SetSize(Source.Height, Source.Width);
AGraphic.BeginUpdate();
for LineIndex := 0 to Source.Height - 1 do
begin
SourceLine := Source.ScanLine[LineIndex];
for PixelIndex := 0 to Source.Width - 1 do
begin
GraphicLine := AGraphic.ScanLine[AGraphic.Height - PixelIndex - 1];
GraphicLine^[LineIndex] := SourceLine^[PixelIndex];
end;
end;
finally
AGraphic.EndUpdate();
Source.EndUpdate();
Source.Free();
end;
end;
I hope these codes are helpful.