Home » Tutorials » Grafik und Spiele » Bitmaps

Bitmaps

Überblenden

Um vom einem Bitmap zum anderen zu Überblenden, empfiehlt sich zunächst einmal die Verwendung der TTrackBar-Komponente, z.B. mit einem Wertebereich von 0 – 100. Dann brauchen wir noch drei Bilder. Eigentlich würden auch zwei genügen, aber am anschaulichsten ist es, wenn ein Bild das Ausgangsbild darstellt, eines das Endbild und eines das Resultat, also die Kreuzung aus den beiden anderen.
Wenn also der Trackbar auf Null steht, soll das Anfangsbild dem Resultat entsprechen, steht er auf 100, soll das Endbild dem Resultat entsprechen.
Die Überlegung ist nicht schwer:
Der Unterschiedswert zwischen jedem Pixel des Anfangsbildes und jedem Pixel des Endbildes muss durch 100 geteilt werden, um die Abstufungen mit dem Trackbar konform zu setzen. Das Ergebnis hiervon muss sovielmal zu dem Pixelwert der Anfangsbildes gezählt werden, wie der Trackbar es vorgibt.
Die Formel dazu:

n= neuer Farbwert
a= Anfangswert
e= Endwert

n = a – ((a – e) / 100 * TrackBar1.Position)

Das Programm zeigt im Bezug auf die Verwendung von ScanLine noch einen Unterschied zu den bisherigen Beispielen:

PByteArray

Bisher haben wir uns immer mit drei Farbwerten pro Pixel herumgeplagt (was auch immer erforderlich war), aber bei diesem Beispiel muss nicht jeder Farbwert einzeln behandelt werden. Und dazu brauchen wir uns auch nicht mehr selber einen Zeigertyp zu bilden, denn hierfür gibt es den von Delphi bereitgestellten Typ ‚PByteArray‘. In diesem Array werden alle von ScanLine ermittelten Pixelwerte einer Bitmap-Reihe gesammelt (bzw. es wird von PByteArray darauf gezeigt). Da aber trotzdem dreimal soviele Byte-Werte in einer Bitmap-Reihe erscheinen wie Pixel vorhanden sind, muss diesmal der Endwert der bekannten For-Schleife, die die Pixelwerte in Horizontaler Lage ausliest, mit drei multipliziert werden.
Das ist anfangs vielleicht etwas verwirrend, aber einiges herumprobieren wird zu den nötigen Aha-Effekten führen.
Kurz und bündig:

procedure TForm1.Blend(FromBit, ToBit, NewBit: TBitmap);
var
  pt, pf, pn: PByteArray;
  h, w: Integer;
begin
  for h:=0 to ToBit.Height-1 do
  begin
    pt:= ToBit.ScanLine[h];
    pf:= FromBit.ScanLine[h];
    pn:= NewBit.ScanLine[h];
    for w:=0 to (ToBit.Width *3)-1 do
      pn^[w]:= round(pf^[w] - ((pf^[w]-pt^[w]) / 100 *
      TrackBar1.Position));
  end;
end;