Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi transparentes bild über form legen und hin und her blenden (https://www.delphipraxis.net/55694-transparentes-bild-ueber-form-legen-und-hin-und-her-blenden.html)

n0b0dy 25. Okt 2005 15:12


transparentes bild über form legen und hin und her blenden
 
hi,

habe mal ein frage undzwar:

ich habe eine form mit einem hintergrund bild.
nun möchte ich das dieses hintergrund mit was transparenten überdeckt wird, was dann nach einer zeit wieder langsam sichtbar wird. und das immer hin und her...

habe leider kA wie ich das anfangen soll. hab hier im forum verschiedenes gesehen, wie man eine form überdeckt, nur leider wird das immer wieder und wieder überdeckt, bis ich nix mehr sehe... aber sichtbar krieg ichs net.

kann mir jemand helfen?

Ciao

Khabarakh 25. Okt 2005 15:30

Re: transparentes bild über form legen und hin und her blend
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ehrlich gesagt habe ich fast nichts von deinem Post verstanden. Wenn du ein Bild über ein anderes legen willst (also blenden), solltest du dir die GR32-Lib anschauen.

n0b0dy 25. Okt 2005 15:35

Re: transparentes bild über form legen und hin und her blend
 
ehm ne sowas net.
hatte mich vllt komisch ausgedrückt, also nochmal:

mein programm hat als hintergrund ein bild. so dieses bild soll die ganze zeit hin und her "faden" (überblenden) also von sichtbar nach unscihtbar und von unsichtbar nach sichtbar....

(hätt ich eigentlich gleich so beschreiben können :D)


hoffe is nun verständlicher.

Khabarakh 25. Okt 2005 15:58

Re: transparentes bild über form legen und hin und her blend
 
Zitat:

Zitat von n0b0dy
hoffe is nun verständlicher.

Naja, etwas *g* . Fading ist ja auch nichts anderes als Blending, also brauchst zwei Bilder (Bitmaps, HDCs, ...). Das erste ist ein Hintergrundbild, ok. Aber das zweite :wink: ? Wenn du den Desktop meinst, also das ganze Fenster mit dem Hintergrund blenden willst, musst du TForm.AlphaBlendValue in einem Timer verändern. Wenn du das "Fenster-Grau" (also Bitmap auf die Formcanvas blenden) meinst, würde ich die GR32-Lib dazu nutzen. Du kannst aber auch per Scanline von Hand jedes Pixel mit clBtnFace mischen.

n0b0dy 25. Okt 2005 16:01

Re: transparentes bild über form legen und hin und her blend
 
neee auch net *g*

der hintergrund is schwarz und in der mitte ein bild. ein logo gewissermaßen ;)

und dieses logo soll AUF der FORM immer verschwinden und wieder auftauchen....also einmal hab ich eine form die ganz schwarz ist, paar sekunden später eine schwarze form, die ein logo in der mitte hat ;)

das will ich *g*

ichbins 25. Okt 2005 16:07

Re: transparentes bild über form legen und hin und her blend
 
wie gesagt: GR32 Download

n0b0dy 25. Okt 2005 16:12

Re: transparentes bild über form legen und hin und her blend
 
aha.
hier gibts ja richtig "viel" darüber ^^

gibts da nicht eine methode, die auch so mit delphi geht, ohne zusatzkram?

Khabarakh 25. Okt 2005 16:14

Re: transparentes bild über form legen und hin und her blend
 
Gut, das fällt unter Vermutung zwei :wink: . Du brauchst einen Alpha-Wert (Byte), den du in einem Timer immer zwischen 255 und 0 pendeln lässt. Das Logo hast du in einem TBitmap(32), dieses blendest du mit dem Hintergrund auf ein TImage(32).
Drei Ansätze zum Blenden:
- TCanvas.Pixels (langsam)
- TBitmap.Scanline (Pointer :wink: )
- GR32

Pseudocode für 1 und 2:
Delphi-Quellcode:
RGB(Image) = RGB(Bitmap) * Alpha + RGB(Background) * (255 - Alpha)
Nummer drei benötigt etwas Einarbeitung in die Lib, dafür wirds dann ziemlich schnell (vom Code und der Ausführung):
Delphi-Quellcode:
for i := 0 to Image.Height * Image.Width -1 do
  Image.Bits[i] := BlendReg(Alpha shl 24, Bit.Bits[i]);
EMMS;
oder auch
Delphi-Quellcode:
// Bit.DrawMode = dmBlend
Image.Bitmap.Clear(Alpha shl 24);
Image.Bitmap.Draw(0, 0, Bit);

[edit]Zuu langsam :stupid: . Passt trotzdem. [/edit]

n0b0dy 25. Okt 2005 16:19

Re: transparentes bild über form legen und hin und her blend
 
ochnä. das is mir nun zuviel arbeit. dachte das könnt ich eben schnell mal machen.

entweder ich lass das sein oder mach eine gifanimation da draus ;)

Khabarakh 25. Okt 2005 16:24

Re: transparentes bild über form legen und hin und her blend
 
Wenn man etwas Ahnung hat, geht das ziemlich schnell :P . Außerdem musst du doch mal was Neues lernen :wink: . Oder willst du dich dem Grafik-Bereich für immer verschließen?

n0b0dy 25. Okt 2005 16:26

Re: transparentes bild über form legen und hin und her blend
 
naja dann hab ich eben keine ahung ;)

TeronG 25. Okt 2005 16:28

Re: transparentes bild über form legen und hin und her blend
 
Zitat:

Zitat von n0b0dy
entweder ich lass das sein oder mach eine gifanimation da draus ;)

:gruebel: wenn du die schneller schaffst ... :zwinker:

n0b0dy 25. Okt 2005 16:29

Re: transparentes bild über form legen und hin und her blend
 
vllt net schneller, aber einfacher *g*

jedenfalls bin ich heute zufaul was neues zu lernen *g*

Khabarakh 25. Okt 2005 16:31

Re: transparentes bild über form legen und hin und her blend
 
Zitat:

Zitat von n0b0dy
naja dann hab ich eben keine ahung ;)

Deswegen musst du jetzt dieses Projekt machen, dann hast du nächstes Mal etwas mehr Ahnung von Scanline, ABGR und Co. :wink: .

[add] Nagut, lassen wirs *g* [/add]

n0b0dy 25. Okt 2005 16:33

Re: transparentes bild über form legen und hin und her blend
 
jo find ich auch *g*
und wenn cih doch mal bock habe, komm ich auf dich zurück ;)

SirThornberry 25. Okt 2005 16:39

Re: transparentes bild über form legen und hin und her blend
 
ach Leute, benutzt doch mal die Forensuche und verweist nicht immer nur auf die GR32. Windows hat doch alles was man dazu braucht dabei. In der Unit Windows ist die Funktion Alphablend definiert mit der man Bilder blenden kann.
@Threadsteller: Soll das bild über dem gesammten form liegen oder nur an einer bestimmten Stelle? Wenn du die Info preisgibst ist das ganze nur ne Sache von 2 bis 3 Minuten

n0b0dy 25. Okt 2005 16:46

Re: transparentes bild über form legen und hin und her blend
 
hey cool. endlcih einer, ders einfach macht *g* und ohne dieses GR32 (und ohne gif *g*)

also das bild is genau in der mitte von der form undzwar 200x200px

SirThornberry 25. Okt 2005 17:52

Re: transparentes bild über form legen und hin und her blend
 
so hier mal der Quelltext meiner kleine Klasse die dafür da ist (man sollte bei sowas doublebuffered des Form auf True setzen)
Delphi-Quellcode:
  TFadeImage = class(TGraphicControl)
  private
    fAlphaVal: Byte;
    fBitmap: TGraphic;
    procedure FOnBitmapChanged(Sender: TObject);
    procedure FSetAlphaVal(AValue: Byte);
    procedure FSetBitmap(ABitmap: TGraphic);
  public
    property AlphaVal: Byte read fAlphaVal write FSetAlphaVal;
    property Graphic: TGraphic read fBitmap write FSetBitmap;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Paint; override;
  end;
[...]
procedure TFadeImage.FOnBitmapChanged(Sender: TObject);
begin
  Repaint;
end;

procedure TFadeImage.FSetAlphaVal(AValue: Byte);
begin
  if AValue <> fAlphaVal then
  begin
    fAlphaVal := AValue;
    if Assigned(Parent) and Parent.HandleAllocated then
      Repaint;
  end;
end;

procedure TFadeImage.FSetBitmap(ABitmap: TGraphic);
begin
  if ABitmap <> fBitmap then
  begin
    if ABitmap = nil then
      FreeAndNil(fBitmap)
    else begin
      if fBitmap = nil then
        fBitmap := TBitmap.Create;
      fBitmap.Assign(ABitmap);
      fBitmap.OnChange := FOnBitmapChanged;
    end;
    Repaint;
  end;
end;

constructor TFadeImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fAlphaVal := 255;
end;

destructor TFadeImage.Destroy;
begin
  inherited Destroy;
  if Assigned(fBitmap) then
    fBitmap.Free;
end;

procedure TFadeImage.Paint;
var LBlendFunc: TBlendFunction;
begin
  if (fAlphaVal <> 0) and Assigned(fBitmap) then
  begin
    SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
    SetBrushOrgEx(Canvas.Handle, 0, 0, nil);
    LBlendFunc.BlendOp := AC_SRC_OVER;
    LBlendFunc.BlendFlags := 0;
    LBlendFunc.SourceConstantAlpha := fAlphaVal;
    LBlendFunc.AlphaFormat := 0;
    windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height, TBitmap(fBitmap).Canvas.Handle,
                       0, 0, fBitmap.Width, fBitmap.Height, LBlendFunc);
  end;
end;

Wenn das ganze nicht mit dem Untergrund, sondern mit einer festen farbe blenden soll dann kann das ganze auch so aussehen und doublebuffered ist nicht notwendig. Die Farbe mit der geblendet werden soll wird über das Property "Color" festgelegt.
Delphi-Quellcode:
  TFadeImage = class(TGraphicControl)
  private
    fAlphaVal: Byte;
    fBitmap: TGraphic;
    procedure FOnBitmapChanged(Sender: TObject);
    procedure FSetAlphaVal(AValue: Byte);
    procedure FSetBitmap(ABitmap: TGraphic);
  public
    property AlphaVal: Byte read fAlphaVal write FSetAlphaVal;
    property Color;
    property Graphic: TGraphic read fBitmap write FSetBitmap;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Paint; override;
  end;

[...]

procedure TFadeImage.FOnBitmapChanged(Sender: TObject);
begin
  Paint;
end;

procedure TFadeImage.FSetAlphaVal(AValue: Byte);
begin
  if AValue <> fAlphaVal then
  begin
    fAlphaVal := AValue;
    if Assigned(Parent) and Parent.HandleAllocated then
      Paint;
  end;
end;

procedure TFadeImage.FSetBitmap(ABitmap: TGraphic);
begin
  if ABitmap <> fBitmap then
  begin
    if ABitmap = nil then
      FreeAndNil(fBitmap)
    else begin
      if fBitmap = nil then
        fBitmap := TBitmap.Create;
      fBitmap.Assign(ABitmap);
      fBitmap.OnChange := FOnBitmapChanged;
    end;
    Repaint;
  end;
end;

constructor TFadeImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fAlphaVal := 255;
end;

destructor TFadeImage.Destroy;
begin
  inherited Destroy;
  if Assigned(fBitmap) then
    fBitmap.Free;
end;

procedure TFadeImage.Paint;
var LBlendFunc: TBlendFunction;
    LBitmap: TBitmap;
begin
  if (fAlphaVal <> 0) and Assigned(fBitmap) then
  begin
    LBitmap := TBitmap.Create;
    LBitmap.Width := Width;
    LBitmap.Height := Height;

    SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
    SetBrushOrgEx(Canvas.Handle, 0, 0, nil);
    LBlendFunc.BlendOp := AC_SRC_OVER;
    LBlendFunc.BlendFlags := 0;
    LBlendFunc.SourceConstantAlpha := fAlphaVal;
    LBlendFunc.AlphaFormat := 0;
    LBitmap.Canvas.Brush.Color := Color;
    LBitmap.Canvas.FillRect(Rect(0, 0, Width, Height));
    windows.AlphaBlend(LBitmap.Canvas.Handle, 0, 0, Width, Height, TBitmap(fBitmap).Canvas.Handle,
                       0, 0, fBitmap.Width, fBitmap.Height, LBlendFunc);
    BitBlt(Canvas.Handle, 0, 0, Width, Height, LBitmap.Canvas.Handle, 0, 0, SRCCOPY);
    LBitmap.Free;
  end;
end;
[Edit]
So, habs nun nach Anfangsschwierigkeiten es auch hinbekommen das ganze auf ein TImage anzuwenden. Also einfach wie gewohnt TImages aufs Form schmeißen, bissl quelltext (den ich dann gleich nachreiche) schreiben und schon kann TImage auch Alphatransparenz.

SirThornberry 25. Okt 2005 18:18

Re: transparentes bild über form legen und hin und her blend
 
So hier das was ich im Edit geschrieben hab. Ich mach mal einen eigenen Beitrag draus damit es nicht untergeht.
So bringt man TImage die Alphatransparenz bei:
In die Unit wo das TImage die Transparenz beherrschen soll (standardmäßig unit1) muss folgendes mit rein
Delphi-Quellcode:
type
  TGraphicControl = class(Controls.TGraphicControl);
  TImage = class(ExtCtrls.TImage)
  private
    fAlphaVal: Byte;
    procedure FSetAlphaVal(AValue: Byte);
  public
    constructor Create(AOwner: TComponent); override;

    property AlphaVal: Byte read fAlphaVal write FSetAlphaVal;
    procedure Paint; override;
  end;
[...]
constructor TImage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fAlphaVal := 255;
end;

procedure TImage.Paint;
type
  PControlStyle = ^TControlStyle;
  PCanvas = ^TCanvas;
var LBitmap: TBitmap;
    LOldCanvas: TCanvas;
    LBlendFunc: TBlendFunction;
begin
  if fAlphaVal = 255 then
    inherited Paint
  else if fAlphaVal > 0 then
  begin
    LBitmap := TBitmap.Create;
    LBitmap.Width := Width;
    LBitmap.Height := Height;

    if csOpaque in ControlStyle then
      ControlStyle := ControlStyle - [csOpaque];

    LOldCanvas := TGraphicControl(Self).Canvas;
    PCanvas(@TGraphicControl(Self).Canvas)^ := LBitmap.Canvas;

    //aktullen Hintergrund Holen
    BitBlt(LBitmap.Canvas.Handle, 0, 0, Width, Height, LOldCanvas.Handle, 0, 0, SRCCOPY);
    inherited Paint;

    LBlendFunc.BlendOp := AC_SRC_OVER;
    LBlendFunc.BlendFlags := 0;
    LBlendFunc.SourceConstantAlpha := fAlphaVal;
    LBlendFunc.AlphaFormat := 0;

    windows.AlphaBlend(LOldCanvas.Handle, 0, 0, Width, Height, LBitmap.Canvas.Handle,
                       0, 0, Width, Height, LBlendFunc);

    PCanvas(@TGraphicControl(Self).Canvas)^ := LOldCanvas;

    if csOpaque in ControlStyle then
      ControlStyle := ControlStyle - [csOpaque];
    LBitmap.Free;
  end;
end;

procedure TImage.FSetAlphaVal(AValue: Byte);
begin
  if AValue <> fAlphaVal then
  begin
    fAlphaVal := AValue;
    Repaint;
  end;
end;
Alternativ kann man diese Klasse auch in eine eigene Unit packen und diese Unit hinter/nach der Unit ExtCtrls in die Uses aufnehmen.

n0b0dy 25. Okt 2005 18:31

Re: transparentes bild über form legen und hin und her blend
 
cool. hab hier die letzte methode probiert.

es funktioniert zwar, aber leider fadet der nicht so schön, als wenn man den alphavalue wert von einem formular ändert....
und flackern tuts auch ein wenig.
Delphi-Quellcode:
DoubleBuffered := True
hab ich im FormCreate gemacht.

SirThornberry 25. Okt 2005 18:35

Re: transparentes bild über form legen und hin und her blend
 
das Flackert hängt eben mit der Berechnung zusammen weil die nicht gering ist, wenn das bild recht klein ist ist die performance eigentlich recht ok.

n0b0dy 25. Okt 2005 18:37

Re: transparentes bild über form legen und hin und her blend
 
okay. dann versuch ich das mal zu verkleinern.
will ja nicht, dass leute mit schwacher cpu das programm net verwenden können, wegen so einem kleinen schönen nebeneffekt^^

n0b0dy 25. Okt 2005 18:51

Re: transparentes bild über form legen und hin und her blend
 
habe es nun mit einem kleineren bild nochmal gemacht. flackern is weg.
problem ist nur, dass der bei alphaval = 0 garnicht ganz bedeckt ist....der soll von sichtbar bis unsichtbar, wenn das geht.
und dann nochne kleinigkeit. die geschwindigkeit: hab einen TTimer mit intervall=1 und es ist mir eigentlich noch ein bissle zu langsam. kA ob meine cpu nix taugt, aber hab nen AMD Athlon XP 2400+. sollte ja eigentlich für sowas genügen ;)

Stanlay Hanks 25. Okt 2005 19:09

Re: transparentes bild über form legen und hin und her blend
 
Zitat:

Zitat von n0b0dy
hab einen TTimer mit intervall=1 und es ist mir eigentlich noch ein bissle zu langsam. kA ob meine cpu nix taugt, aber hab nen AMD Athlon XP 2400+. sollte ja eigentlich für sowas genügen ;)

"Timer.Interval := 1" kannst du vergessen. Das ist ein geradezu utopisch kleiner Wert, so schnell kann ein TimerEvent in der Praxis gar nicht ausgelöst werden ;)
Wenn es dir zu langsam geht, bleibt eigentlich nur die Möglichkeit, die Schritte im Alphablend zu vergrößern, also nicht von 255 auf 254 auf 253, sondern eben z.B. von 255 auf 250 auf 245 usw.

Man liest sich, Stanlay :hi:

n0b0dy 25. Okt 2005 19:10

Re: transparentes bild über form legen und hin und her blend
 
hm okay. dann mach ich das so. und wie siehts damit aus, dass bei AlphaVal = 0 nicht alles bedeckt ist?

SirThornberry 25. Okt 2005 19:22

Re: transparentes bild über form legen und hin und her blend
 
was meinst du mit bedeckt? wenn ich es bei mir auf 0 einstelle dann sehe ich von dem Bild nix mehr (sehe also nur noch den Untergrund vom Form). Bei 255 sehe ich dann wieder das komplette bild (ohne transparenz)

n0b0dy 25. Okt 2005 19:41

Re: transparentes bild über form legen und hin und her blend
 
das ist ja das. bei mir sehe ich das bei 0 immer noch ein wenig.

SirThornberry 25. Okt 2005 19:49

Re: transparentes bild über form legen und hin und her blend
 
wie zählst du für den fade den alphawert herunter? Eventuell erzeugst du einen Überlauf.

Wenn du also "alphaval := alphaval - 11" machst und alphaval ist nur "5" dann kommt dort "-6" heraus und das ergibt dann beim überlauf "250". Das ganze sollte dann also so aussehen
"alphaval := max(0, alphaval - 11)"

n0b0dy 25. Okt 2005 19:52

Re: transparentes bild über form legen und hin und her blend
 
sry, daran hatte ich net gedacht

okay :)) so klappts bestens.


Danke nochmal :) :thumb:

n0b0dy 25. Okt 2005 20:57

Re: transparentes bild über form legen und hin und her blend
 
Liste der Anhänge anzeigen (Anzahl: 2)
ich muss nochmal nachfragen:

manche bilder lassen sich einfach nicht faden. welcher typ muss es denn sein? bei mir klappt das nur mit ico.
hab mal 2 angehängt. mit dem einen klappts, mit dem andern net. woran könnte das liegen?

SirThornberry 25. Okt 2005 21:00

Re: transparentes bild über form legen und hin und her blend
 
was heißt "lässt sich nicht faden"? Passiert gar nix, wird das bild also mit voller Deckkraft dargestellt?
Hab das ganze auch grad nochmal probiert und festgestellt das, dass faden nur geht wenn das Bild nicht größer ist als der darstellbare Bereich.

[Edit]
Hab gerade den Quelltext geändert in dem entsprechenden Beitrag (also einfach nochmal neu kopieren). Die Änderung ist in der Methode "TImage.Paint"

n0b0dy 25. Okt 2005 21:35

Re: transparentes bild über form legen und hin und her blend
 
okay :) nun ists aber endgültig genial :))

Suuper. Danke nochmals!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz