Thema: Delphi hintergrundefekt

Einzelnen Beitrag anzeigen

xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#8

Re: hintergrundefekt

  Alt 13. Mai 2006, 13:01
Hallo,

im Grunde brauchst Du dafür drei Funktionen:
Eine, die ein Graustufenbild erzeugt.
Eine, die zwei Bilder überlagert
Eine, die diese Überlagerung in einer Schleife widerholt.

Ich hab mal diese drei Funktionen geschrieben. Du brauchst nur noch ein TImage und einen Button:
Delphi-Quellcode:
procedure ToGray(const Bitmap: TBitmap);
var
  Trip: PRGBTriple;
  P: PByte;
  PixelCount: Integer;
  C: Integer;
  Gray: Byte;
  Alignment: Byte;
begin
  if not (Bitmap.PixelFormat in [pf24Bit, pf32Bit]) then
    Exit;

  // Vorbereitungen
  P := Bitmap.ScanLine[Bitmap.Height - 1];

  // Alignment berechnen
  if (Bitmap.PixelFormat = pf24Bit) then
    Alignment := (4 - (Bitmap.Width * 3) mod 4) mod 4
  else
    Alignment := 0;

  // In einer Schleife alle Pixel durchgehen
  PixelCount := Bitmap.Width * Bitmap.Height;
  for C := 0 to PixelCount - 1 do
  begin
    //Pixel holen
    Trip := PRGBTriple(P);

    // Graustufenberechnung
    Gray := Round(Trip.rgbtBlue * 0.114 + Trip.rgbtGreen * 0.578 + Trip.rgbtRed * 0.299);
    Trip.rgbtBlue := Gray;
    Trip.rgbtGreen := Gray;
    Trip.rgbtRed := Gray;

    // Nächster Pixel
    Inc(P, 3);
    if Bitmap.PixelFormat = pf32Bit then
      Inc(P);

    // Alignment am Ende der Zeile
    if (C > 0) and (C mod Bitmap.Width = 0) then
      Inc(P, Alignment);
  end;
end;

function Fade(const Bitmap1, Bitmap2: TBitmap; Delta: Byte): TBitmap;
var
  Trip1, Trip2, TripR: PRGBTriple;
  P1, P2, PR: PByte;
  PixelCount: Integer;
  C: Integer;
  Alignment1, Alignment2, AlignmentR: Byte;

begin
  Result := nil;
  if (Bitmap1 = nil) or (Bitmap2 = nil) or
     (Bitmap1.Width <> Bitmap2.Width) or (Bitmap1.Height <> Bitmap2.Height) or
     not (Bitmap1.PixelFormat in [pf24Bit, pf32Bit]) or
     not (Bitmap2.PixelFormat in [pf24Bit, pf32Bit]) then
  Exit;

  // Vorbereiten
  Result := TBitmap.Create;
  Result.PixelFormat := pf24Bit;
  Result.Width := Bitmap1.Width;
  Result.Height := Bitmap1.Height;

  P1 := Bitmap1.ScanLine[Bitmap1.Height - 1];
  P2 := Bitmap2.ScanLine[Bitmap2.Height - 1];
  PR := Result.ScanLine[Result.Height - 1];

  // Alignment berechnen
  if (Bitmap1.PixelFormat = pf24Bit) then
    Alignment1 := (4 - (Bitmap1.Width * 3) mod 4) mod 4
  else
    Alignment1 := 0;

  if (Bitmap2.PixelFormat = pf24Bit) then
    Alignment2 := (4 - (Bitmap2.Width * 3) mod 4) mod 4
  else
    Alignment2 := 0;

  AlignmentR := (4 - (Result.Width * 3) mod 4) mod 4;

  // In einer Schleife alle Pixel durchgehen
  PixelCount := Result.Width * Result.Height;
  for C := 0 to PixelCount - 1 do
  begin
    // Pixel holen
    Trip1 := PRGBTriple(P1);
    Trip2 := PRGBTriple(P2);
    TripR := PRGBTriple(PR);

    // Faden
    TripR.rgbtBlue := Round((Trip1.rgbtBlue * Delta + Trip2.rgbtBlue * (255 - Delta)) / 255);
    TripR.rgbtGreen := Round((Trip1.rgbtGreen * Delta + Trip2.rgbtGreen * (255 - Delta)) / 255);
    TripR.rgbtRed := Round((Trip1.rgbtRed * Delta + Trip2.rgbtRed * (255 - Delta)) / 255);

    // Nächster Pixel
    Inc(P1, 3);
    Inc(P2, 3);
    Inc(PR, 3);
    if Bitmap1.PixelFormat = pf32Bit then
      Inc(P1);
    if Bitmap2.PixelFormat = pf32Bit then
      Inc(P2);

    // Alignment am Ende der Zeile
    if (C > 0) and (C mod Result.Width = 0) then
    begin
      Inc(P1, Alignment1);
      Inc(P2, Alignment2);
      Inc(PR, AlignmentR);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  B1, B2: TBitmap;
  I: Integer;
  Count, Delta: Integer;
begin
  try
    Screen.Cursor := crHourglass;
    // Bilder vorbereiten
    B1 := TBitmap.Create;
    B1.Assign(Image1.Picture.Bitmap);
    B2 := TBitmap.Create;
    B2.Assign(B1);
    ToGray(B2);

    // Die Schleife
    // einfach mal mit den Werten spielen,
    // aber (Count - 1) * Delta darf nicht größer sein als 255!
    Count := 20;
    Delta := 12;
    for I := 0 to Count - 1 do
    begin
      Image1.Picture.Bitmap := Fade(B1, B2, 255 - I * Delta);
      Image1.Update;
    end;
  finally
    B2.Free;
    B1.Free;
    Screen.Cursor := crDefault;
  end;
end;
Gruß
xaromz
  Mit Zitat antworten Zitat