AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi AlphaBlending und Canvas der Oberklasse
Thema durchsuchen
Ansicht
Themen-Optionen

AlphaBlending und Canvas der Oberklasse

Ein Thema von Merlin1988 · begonnen am 24. Nov 2005 · letzter Beitrag vom 30. Nov 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Merlin1988
Merlin1988

Registriert seit: 10. Aug 2005
33 Beiträge
 
Delphi 6 Enterprise
 
#1

AlphaBlending und Canvas der Oberklasse

  Alt 24. Nov 2005, 20:25
Ich teste gerade ein bißchen mit dem AlphaBlending. Diese Komponente soll nur ein Test sein.
Ich hab das Problem, dass er zwar blendet, aber nicht auf dem Hintergrund sondern auf einer weißen Fläche. Das hängt anscheinend mit dem verändern des Canvas in der Oberklasse zusammen. Ich will, dass die Prozedur "Paint" aus der Oberklasse nicht direkt auf den Canvas, sondern auf ein Bitmap zeichnet, damit ich nachher flackern vermeiden kann. Allerdings funktioniert das Ändern des Canvas nicht richtig.

Delphi-Quellcode:
unit TransparentTest;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics;

type
  TTransparentTest = class(TGraphicControl)
  private
    { Private declarations }
    FColor: TColor;
    FAlphaValue: Byte;
    procedure SetColor(const Value: TColor);
    procedure SetAlphaValue(const Value: Byte);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Paint; override;
  published
    { Published declarations }
    property Color : TColor read FColor write SetColor;
    property AlphaValue: Byte read FAlphaValue write SetAlphaValue;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Tests', [TTransparentTest]);
end;

{ TTransparentTest }

constructor TTransparentTest.Create(AOwner: TComponent);
begin
  inherited;
end;

procedure TTransparentTest.Paint;
type
  PCanvas = ^TCanvas;
var FarbBitmap: TBitmap;
    NextBitmap: TBitmap;
    LOldCanvas: TCanvas;
    LBlendFunc: TBlendFunction;
begin
  FarbBitmap := TBitmap.Create;
  FarbBitmap.Width := Width;
  FarbBitmap.Height := Height;
  FarbBitmap.Canvas.Brush.Color := FColor;
  FarbBitmap.Canvas.FillRect(FarbBitmap.Canvas.ClipRect);

  NextBitmap := TBitmap.Create;
  NextBitmap.Width := Width;
  NextBitmap.Height := Height;

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

  LOldCanvas := Canvas;
  PCanvas(@Canvas)^ := NextBitmap.Canvas;
  inherited Paint;
  PCanvas(@Canvas)^ := LOldCanvas;

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

  BitBlt(Canvas.Handle,0,0,Width,Height,NextBitmap.Canvas.Handle,0,0,SRCCOPY);

  FarbBitmap.Free;
  NextBitmap.Free;
end;

procedure TTransparentTest.SetAlphaValue(const Value: Byte);
begin
  FAlphaValue := Value;
  Invalidate;
end;

procedure TTransparentTest.SetColor(const Value: TColor);
begin
  FColor := Value;
  Invalidate;
end;

end.
Use the Source, Luke.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: AlphaBlending und Canvas der Oberklasse

  Alt 24. Nov 2005, 21:13
erstmal ist dein fColor undefiniert (außer man ruft die SetColor auf), also einfach einen Startwert im Create dafür vergeben (für Alpha am besten auch gleich mit).

Und dann zu deinem eigentlichen Problem. Ich verstehe nicht warum du inherited Paint aufrufst und davor die Canvas umbiegst und danach wieder zurück.
Es reicht aus wenn du einfach mit AlphaBlend direkt auf die Originalcanvas das Blending ausführst. Denn das "inherited Paint" sorgt dafür das deine gesammte Canvas eingefärbt wird und somit blendest du anschließend dein FarbBitmap mit einer bereits komplett eingefärbten Grundfläsche.

Also folgende Zeilen entfernen:
Delphi-Quellcode:
 LOldCanvas := Canvas;
  PCanvas(@Canvas)^ := NextBitmap.Canvas;
  inherited Paint;
  PCanvas(@Canvas)^ := LOldCanvas;
[...]
BitBlt(Canvas.Handle,0,0,Width,Height,NextBitmap.Canvas.Handle,0,0,SRCCOPY);
Dann sollte anschließend auch FarbBitmap mit dem Hintergrund der Komponenten geblendet sein.

(wenn du nur den Hintergrund der Komponente mit einer Farbe blenden willst muss FarbBitmap auch nicht genau so groß sein wie deine Komponente (reicht 1pixel * 1pixel und dann kann die Funktion Alphablend dafür sorgend das die Farbfläche auf volle größe gestretcht wird)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Merlin1988
Merlin1988

Registriert seit: 10. Aug 2005
33 Beiträge
 
Delphi 6 Enterprise
 
#3

Re: AlphaBlending und Canvas der Oberklasse

  Alt 25. Nov 2005, 05:45
Inherited Paint ohne alles würde aber auf den Canvas der Komponente zeichnen. Da ich aber nachher noch auf den Canvas blenden muss, würde ich zwei Zeichenoperationen auf dem Canvas in einem Aufruf von "Paint" haben. Genau das will ich verhindern, damit ich auch schon das Flackern in der Komponente selbst ein bißchen eindämmen kann.
Use the Source, Luke.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: AlphaBlending und Canvas der Oberklasse

  Alt 25. Nov 2005, 06:07
das inherited Paint kann ganz weg. Wenn du mehrere Dinge blenden willst und erst beim letzten Schritt alles auf die richtige Canvas bringen willst dann ändere bei Alphablend den ersten Parameter und gibt dort statt der richtigen Canvas dein NewPic an.
Delphi-Quellcode:
//erstes Blending auf das Tempbild
windows.AlphaBlend(NeuesBild.Canvas.Handle, 0, 0, Width, Height, FarbBitmap.Canvas.Handle,
                     0, 0, Width, Height, LBlendFunc);
//zweites Blending auf die richtige Canvas
windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height, NeuesBild.Canvas.Handle,
                     0, 0, Width, Height, LBlendFunc);
Dadurch das du zur Zeit hinter dem Alphablend noch BitBlt hast übermalst du mit BitBlt das geblendete. Du malst also im ersten Schritt mit AlphaBlend deine geblendete Farbe und danach übermalst du die geblendete Canvas wieder mit NextBitmap (durch BitBlt)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Merlin1988
Merlin1988

Registriert seit: 10. Aug 2005
33 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: AlphaBlending und Canvas der Oberklasse

  Alt 29. Nov 2005, 16:26
Delphi-Quellcode:
unit BildLabel;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Graphics, Forms, StdCtrls;
  
type
  TBildLabel = class(TGraphicControl)
  private
    FPicture: TBitmap;
    FAlphaValue: Byte;
    procedure SetPicture(const Value: TBitmap);
    procedure SetAlphaValue(const Value: Byte);
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Paint; override;
  published
    property Picture: TBitmap read FPicture write SetPicture;
    property AlphaValue: Byte read FAlphaValue write SetAlphaValue;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('My Own', [TBildLabel]);
end;

{ TBildLabel }

constructor TBildLabel.Create(AOwner: TComponent);
begin
  inherited;
  FPicture := TBitmap.Create;
  fAlphaValue := 0;
end;

destructor TBildLabel.Destroy;
begin
  FPicture.Free;
  inherited;
end;

procedure TBildLabel.Paint;
var Bitmap: TBitmap;
    BlendFunction: TBlendFunction;
begin
  //Buffer-Bitmap erstellen
  Bitmap := TBitmap.Create;
  Bitmap.Width := Width;
  Bitmap.Height := Height;
  //Picture in Buffer-Bitmap kopieren
  Bitmap.Canvas.StretchDraw(Bitmap.Canvas.ClipRect,FPicture);

  //Buffer-Bitmap in den Canvas laden
  BlendFunction.BlendOp := AC_SRC_OVER;
  BlendFunction.BlendFlags := 0;
  BlendFunction.SourceConstantAlpha := fAlphaValue;
  BlendFunction.AlphaFormat := 0;

  windows.AlphaBlend(Canvas.Handle, 0, 0, Width, Height, Bitmap.Canvas.Handle,
                     0, 0, Width, Height, BlendFunction);

  Bitmap.Free;
end;

procedure TBildLabel.SetAlphaValue(const Value: Byte);
begin
  if FAlphaValue <> Value then begin
    FAlphaValue := Value;
    Invalidate;
  end;
end;

procedure TBildLabel.SetPicture(const Value: TBitmap);
begin
  if FPicture <> Value then begin
    FPicture.Assign(Value);
    Invalidate;
  end;
end;

end.
Die Komponente ist diesmal eine andere, ich hab aber folgendes Problem:

Zur Designzeit ist alles perfekt, zur Laufzeit aber blendet er nicht richtig. Heißt er blendet immer auf einen weißen Hintergrund, anstatt auf den Hintergrund der sich hinter ihm befindet !!??

Use the Source, Luke.
  Mit Zitat antworten Zitat
Benutzerbild von Merlin1988
Merlin1988

Registriert seit: 10. Aug 2005
33 Beiträge
 
Delphi 6 Enterprise
 
#6

Re: AlphaBlending und Canvas der Oberklasse

  Alt 30. Nov 2005, 17:56
Bei der anderen Komponente (s.o) hab ich es jetzt hinbekommen, aber halt bei dieser nicht.

Use the Source, Luke.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: AlphaBlending und Canvas der Oberklasse

  Alt 30. Nov 2005, 18:34
hast du schonmal versucht ob zur Laufzeit "SetPicture" jemals aufgerufen wird? (was jedoch nicht erklärt warum zur Laufzeit das Bild farblos bleibt). Oder hast du zur Laufzeit mal geprüft welche größe fPicture hat?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Merlin1988
Merlin1988

Registriert seit: 10. Aug 2005
33 Beiträge
 
Delphi 6 Enterprise
 
#8

Re: AlphaBlending und Canvas der Oberklasse

  Alt 30. Nov 2005, 18:45
das Problem ist ja nicht FPIcture. Sondern der Hintergrund auf dem geblendet wird. Der ist zur Laufzeit immer weiß. anstatt dem Hintergrund, der sich "Unter/hinter" der Komponente befindet.
Use the Source, Luke.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#9

Re: AlphaBlending und Canvas der Oberklasse

  Alt 30. Nov 2005, 19:12
*Insblauerat* versuch es mal mit Delphi-Referenz durchsuchenTCustomControl als Basisklasse.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: AlphaBlending und Canvas der Oberklasse

  Alt 30. Nov 2005, 19:14
An dem quelltext ist so weit ich sehe alles richtig. Hast du eventuell noch eine andere Unit mit dem gleichen namen wo du noch einen Fehler drin hast (eventuell hast du die Unit mit "speichern unter" an einen anderen Platz befördert). Ich hab der Vermutung das die Unit die zur Designzeit verwendet wird eine andere ist als die welche zur Laufzeit eingebunden wird. Am besten du suchst mal und löschst eine eventuelle vorhandene kopie weg, sowie vorhandene dcu's

@Khabarakh: TCustomControl ist hier der völlig falsche weg da dann die Alphatransparenz nicht funktioniert. TCustomControl hat ein Handle und TGraphicControl nicht womit sich TGraphicControl dank Delphiinternas auf den Parent zeichnet und somit eine Alphatransparenz möglich macht.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz