Das Thema hatten wir hier zwar schon öfter, aber nicht unter dem Gesichtspunkt, den ich hier ansprechen möchte:
Ich nutze zum drehen von 24 bzw. 32 Bitmaps bislang immer die folgende Routine (aus dem Doberenz-Buch):
Delphi-Quellcode:
procedure Drehe90Rechts (bm: TBitmap);
type
TMyHelp = array [0..0] of TRGBQuad;
var
P, Pend : PRGBQuad; x, y, b, h: Integer; RowOut: ^TMyHelp; help: TBitmap;
begin
Bm.pixelformat := pf32bit;
help := TBitmap.create;
help.pixelformat := pf32bit;
b := bm.height;
h := bm.width;
help.SetSize (b, h);
PEnd := Bm.scanline[bm.height-1];
for y := 0 to h-1 do begin
rowout := help.scanline [y];
p := PEnd;
inc (p, y);
for x := 0 to (b-1) do begin
rowout [x] := p^;
inc (p, h);
end;
end;
bm.Assign (help);
help.free;
end;
Ich dachte, OK die nehmen auch für eine 24-Bit-Bitmap eine 32-Bitmap, weil der Compiler die 32-Bits in einem Register direkt kopieren kann. Wenn man sich das in der CPU ansieht, dann stimmt das wohl auch, bei 24 muss er wohl erst 16-Bit und dann noch mal 8 kopieren, dadurch 2 Befehle mehr (siehe anliegenden Screenshot).
Nur: Bei sehr großen Bilder (teste gerade eins im Format 21600 x 10800) braucht er, aber um die 32-Bit-Hilfsbit anzulegen, statt 660 MB bei einer 24 Bit, bei der 32-Bit Bitmap ca. 1 GB zusätzlichen Arbeitsspeicher.
Daher meine Überlegung, statt die Routine mit 32-Bit zu verwenden, bei einer 24-Bit es mit einer 24-Bit routine zu machen.
Delphi-Quellcode:
procedure Drehe90Rechts24 (bm: TBitmap);
type
TMyHelp = array [0..0] of TRGBTriple;
var
P, Pend : PRGBTriple; x, y, b, h: Integer; RowOut: ^TMyHelp; help: TBitmap;
begin
help := TBitmap.create;
help.pixelformat := pf24bit;
b := bm.height;
h := bm.width;
help.SetSize (b, h);
PEnd := Bm.scanline[bm.height-1];
for y := 0 to h-1 do begin
rowout := help.scanline [y];
p := PEnd;
inc (p, y);
for x := 0 to b-1 do begin
rowout [x] := p^;
inc (p, h);
end;
end;
bm.Assign (help);
help.free;
end;
Leider funktioniert die nicht. Komme leider nicht dahinter warum (es fehlen 1-2 Pixel) und bei Bildgrößen mit ungeraden werten geht es nach dem 2. Drehen ganz schief.
Hat einer eine Idee, wie man es richtig machen könnte?