Eine Bitmap abgestuft grauer werden lassen
Ihr kennt doch den Effekt, den Windows beim Anzeigen des "Herunterfahren"-Menüs einsetzt. Der Hintergrund graut langsam aus.
Ich habe diesen Effekt mal implementiert:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| procedure greyout(Bitmap: TBitmap; step, StepsCount: Integer; darkness: byte = 0); type pixel = Array[0..2] Of byte; var p: ^pixel; x, y, temp: Integer; median, redstep, bluestep, greenstep: byte; begin Bitmap.PixelFormat := pf24Bit; if step > stepsCount then step := StepsCount; for y := 0 to Bitmap.Height - 1 do Begin p := Bitmap.ScanLine[y]; for x := 0 to Bitmap.Width - 1 do begin temp := ((p^[0] + p^[1] + p^[2]) Div 3) - darkness; if temp < 0 then temp := 0;
median := temp;
redstep := (median - p^[0]) Div StepsCount; bluestep := (median - p^[1]) Div StepsCount; greenstep := (median - p^[2]) Div StepsCount;
p^[0] := p^[0] + redstep * step; p^[1] := p^[1] + bluestep * step; p^[2] := p^[2] + greenstep * step;
inc(p); end; end; end; |
Zur Erklärung:
Bitmap soll natürlich die zu verändernde Bitmap darstellen.
Wie schon im Titel angegeben, lässt sich der Effekt abgestuft darstellen, wobei StepsCount die Anzahl der Abstufungen darstellt.
Steps soll von 0 bis StepsCount erhöht werden, dieser Parameter sagt aus, der wievielte Schritt bei der Abstufung zurückgegeben wird.
darkness ist der Wert, um den die entgülige Farbe noch verdunkelt wird, damit z.B. die Farbe Weiß auch ausgegraut wird und nicht Weiß bleibt ( (255+255+255) /3 = 255 => Weiß bleibt Weiß). Darkness hat den Standartwert 0, man muss diesen Parameter also garnicht angeben. In diesem Fall wird Weiß dann Weiß bleiben. Man sollte Darkness vielleicht nicht größer als 100 wählen, da sonst schnell das gesamte bild am Ende schwarz ist. Einfach mal damit rumspielen, bis der gewünschte Effekt erreicht wird!
Zur Verwendung:
Man nehme einen TTimer und eine globale Variable
var x: integer;.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.Timer1Timer(Sender: TObject); begin Image1.Picture.Bitmap.LoadFromFile(Filename); grayout(Image1.Picture.Bitmap, x, 30); inc(x); if x > 30 then Timer1.Enabled := false; end; |
So, oder so ähnlich kann der Effekt implementiert werden. Eine Abstufung von 30 Schritten ist schon recht fein.
Die Bitmap muss natürlich nicht immerwieder erneut von der Festplatte geladen werden, sinnvoller ist es sicher, den Inhalt im Speicher zu halten und von diesem neu zu laden; evtl. ein weiteres TBitMap Objekt zur Speicherung der Originaldaten anlegen. Alternativ kann man natürlich auch Speicheroptimiert arbeiten, und das Bild von der Festplatte neu laden, wie in meinem Beispiel.
PS: Falls ich mich bei der Reihenfolge von grün/rot/blau im array[0..2] of Byte geirrt haben sollte, meldet mir das doch bitte, so dass ich es korrigieren kann
Das passiert mir immer wieder...
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.