Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Probleme mit transparentBtl (https://www.delphipraxis.net/138592-probleme-mit-transparentbtl.html)

BAMatze 13. Aug 2009 07:23


Probleme mit transparentBtl
 
Hallo und guten Morgen an alle,

Habe in Ergänzung zu diesem Threat meine Klasse ein wenig umgebaut. Das alte Konzept war ja entsprechend: alle Signale, welche eingehen werden in ein Bild gezeichnet. Dies führte zu einigen Problemen, so dass ich eigentlich nur auf den Eingang von einem einzigen "Kanal" des Oszilloskopen reagieren konnte, da sonst das Bild verzerrt wurde(Zeichnen erfolgt per Event, wenn am Eingang ein Signal/ neuer Wert anliegt).
Das neue Konzept sieht jetzt so aus: Für jeden Kanal wird ein seperates Bitmap erzeugt und ein zusätzliches, welches als "Maske" fungiert. Diese sollen per transparentBtl ineinander gezeichnet werden. Dieses Verfahren hat den Vorteil, dass man einzelne Graphen einfach ausblenden kann und dass nur sich ändernde Signale neu gezeichnet werden müssen. Sicherlich ist der Nachteil, dass die Performance aufgrund der größeren Anzahl an Bildern etwas leidet.

Jetzt habe ich aber das Problem, dass das transparentBlt nich wirklich so funktioniert, wie ich mir das Vorstelle. Aber hier jetzt erstmal ein wenig Quellcode:

Delphi-Quellcode:
procedure TOszilloskop.CombineBitmap(var combinedBmp: TBitmap);
var i: integer;
begin
  transparentBlt(combinedBMP.Canvas.Handle, 0, 0, combinedBMP.width, combinedBMP.Height,
  Fbitmap[0].Canvas.Handle, 0, 0, Fbitmap[0].Width, Fbitmap[0].Height, FCtransparentColor);
  for i := 1 to Length(FSignal)-1 do
    begin
      if FCB_Layer[i-1].Checked then transparentBlt(combinedBMP.Canvas.Handle, 0, 0, combinedBMP.width, combinedBMP.Height,
      Fbitmap[i].Canvas.Handle, 0, 0, Fbitmap[i].Width, Fbitmap[i].Height, FCtransparentColor);
    end;
end;

procedure TOszilloskop.NewPaint(Sender: TObject); // Procedure welche ausgeführt wird bei PaintBox.Refresh
var i: integer;
    tempbmp: TBitmap;
begin
  tempbmp := TBitmap.Create;
  tempbmp.Width := FiDisplayWidth;
  tempbmp.Height := FiDisplayHeight;
  CombineBitmap(tempbmp);
  BitBlt(FPB_Display.Canvas.Handle, 0, 0, FPB_Display.width, FPB_Display.Height,
  tempbmp.Canvas.Handle, 0, 0, SRCCOPY);
  tempbmp.Free;
end;

procedure TOszilloskop.InitBitmap(BitmapNumber: integer);
var i, j: integer;
begin
  // Hintergrundfarbe setzen (transparente Farbe)
  FBitmap[BitmapNumber].Canvas.Pen.Color := FCtransparentColor;
  for i := 0 to Fbitmap[BitmapNumber].Height do
    begin
      FBitmap[BitmapNumber].Canvas.MoveTo(0,i);
      FBitmap[BitmapNumber].Canvas.LineTo(FBitmap[BitmapNumber].Width,i);
    end;
  FBitmap[BitmapNumber].Canvas.Pen.Color := FSignal[BitmapNumber-1].KanalColor;
  for j := 0 to FiDisplayWidth-2 do // Schleife durch Messpunkte
    begin
      // FBitmap[0] = Maske, deswegen gehören immer Fbitmap[i] und FSignal[i-1] zusammen!
      FBitmap[BitmapNumber].Canvas.MoveTo(j, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[j]- FdDisplayMin)*FdDisplayStrech));
      FBitmap[BitmapNumber].Canvas.LineTo(j+1, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[j+1]- FdDisplayMin)*FdDisplayStrech));
    end;
end;

procedure TOszilloskop.Bild_neuzeichnen(BitmapNumber: integer);
var i, j, iChanges: integer;
begin

  FBitmap[BitmapNumber].Canvas.CopyRect(rect(0,0,FiDisplayWidth-1,FiDisplayHeight-1),FBitmap[BitmapNumber].canvas,rect(1,0,FiDisplayWidth,FiDisplayHeight-1));
  FBitmap[BitmapNumber].Canvas.Pen.Color := FCtransparentColor;
  FBitmap[BitmapNumber].Canvas.MoveTo(FiDisplayWidth-1,0);
  FBitmap[BitmapNumber].Canvas.LineTo(FiDisplayWidth-1,FiDisplayHeight);

  FBitmap[BitmapNumber].Canvas.Pen.Color := FSignal[BitmapNumber-1].KanalColor;
  FBitmap[BitmapNumber].Canvas.MoveTo(FiDisplayWidth-2, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[FiDisplayWidth-2]- FdDisplayMin)*FdDisplayStrech));
  FBitmap[BitmapNumber].Canvas.LineTo(FiDisplayWidth-1, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[FiDisplayWidth-1]- FdDisplayMin)*FdDisplayStrech));

  end;

procedure TOszilloskop.Maske_erstellen;
var i: integer;
    dy: double;
begin
  // Striche setzen
  FBitmap[0].Canvas.Pen.Color := FCBackground;
  for i := 0 to Fbitmap[0].Height do
    begin
      FBitmap[0].Canvas.MoveTo(0,i);
      FBitmap[0].Canvas.LineTo(FBitmap[0].Width,i);
    end;
  FBitmap[0].Canvas.Pen.Color := FCMask;
  dy := (FiDisplayHeight-10)/4;
  for i := 0 to 5 do
    begin
      FBitmap[0].Canvas.MoveTo(0, 5+ round(dy * i));
      FBitmap[0].Canvas.LineTo(FiDisplayWidth, 5+ round(dy * i));
    end;
 // horizontale Labels ändern
 for i := 0 to 4 do FLblhorizontal[i].Caption := Format('%.2f',[FdDisplayMin+i*FdDisplayRange/4]);
end;
Es ist nur die Maske zu erkennen. Die graphen werden leider nur gezeichnet wenn ich in der NewPait-procedure das TransparentBtl in ein BitBtl umwandel und 1 Graphen (FBitmap[i]) übergebe.

Hoffe jemand kann mir helfen das Problem zu lösen, habe mich eigentlich an die Beispiele für transparentBtl hier aus der DP gehalten.

Vielen Dank
BAMatze

BAMatze 13. Aug 2009 09:19

Re: Probleme mit transparentBtl
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also habe durch probieren das ganze geschafft. Anscheinend war etwas beim Kopieren auf den das tempbmp in der Newpaint-procedure nicht korrekt. Kopiere jetzt alles in die Maske vor dem Zeichnen und es funktioniert. Leider musste ich für vorerst 100%ige Funktionalität die wahrscheinlich schneller Bild_neuzeichnen (aufgrund der CopyRec im Canvas) gegen die langsamere InitBitmap (Bild wird Zeile für Zeile gelöscht und der Graph komplett neu gezeichnet) ersetzen. Dies war nötig, weil das CopyRec immer zumindest teilweise verschmierte Graphen (meist die ersten beiden Bögen bei einer Sinus-Kurve) erstellte. Diese Fehler sind in der InitBitmap nicht vorhanden.
Stelle euch das mal zur Verfügung, vieleicht hat ja jemand mal Zeit und kann sich das anschauen und Verbesserungsvorschläge machen oder Anregungen geben.
Getestet habe ich das Projekt mit 20 Signalen. Und zumindest optisch war kein großer Performance-Verlust merkbar.

Vielen Dank
BAMatze


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:17 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