AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit transparentBtl

Ein Thema von BAMatze · begonnen am 13. Aug 2009 · letzter Beitrag vom 13. Aug 2009
Antwort Antwort
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Probleme mit transparentBtl

  Alt 13. Aug 2009, 08:23
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
2. Account Sero
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Probleme mit transparentBtl

  Alt 13. Aug 2009, 10:19
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
Angehängte Dateien
Dateityp: zip oszi_800.zip (311,8 KB, 9x aufgerufen)
2. Account Sero
  Mit Zitat antworten Zitat
Antwort Antwort


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 22:48 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