AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Gedimmten Hintergrund im Canvas schneller

Gedimmten Hintergrund im Canvas schneller

Ein Thema von Nic2012 · begonnen am 11. Jun 2013 · letzter Beitrag vom 5. Aug 2013
Antwort Antwort
Nic2012

Registriert seit: 2. Mai 2012
62 Beiträge
 
#1

Gedimmten Hintergrund im Canvas schneller

  Alt 11. Jun 2013, 15:34
Hallo,
habe das TShape für eine eigene Komponente abgeleitet, deren Hintergrund zwar transparent aber gedimmt sein soll. Im Paint rufe ich dazu:
Code:
procedure TExtShape.Paint;
  function Shadow(Color: TColor): TColor;
  const
    Delta = 0.7;
  begin
    Color := ColorToRGB(Color);
    Result := RGB(Round(GetRValue(Color) * Delta),
    Round(GetGValue(Color) * Delta),
    Round(GetBValue(Color) * Delta));
  end;
var y, x: Integer;
begin
  inherited Paint;

  if FIsDimmed then
    for Y := 0 to Height -1 do
      for X := 0 to Width -1 do
        SetPixelV( Canvas.Handle, X, Y, Shadow(GetPixel(Canvas.Handle, X, Y)));

  Canvas.Font := Font;
  Canvas.TextOut((Width - Canvas.TextWidth(Caption)) div 2, (Height - Canvas.TextHeight(Caption)) div 2, Caption);
end;
Das geht prinzipel, aber mit deutlichem Flackern beim Neuzeichnen. Stehe etwas auf dem Schlauch wie das mit z.B. ScanLine schneller bekomme, insbesondere soll das Shape mit RoundRectangle abgerundet sein, und nicht so wie im Screenshot.
Gruß,
Nic
Miniaturansicht angehängter Grafiken
clipboard01.png  
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Gedimmten Hintergrund im Canvas schneller

  Alt 11. Jun 2013, 15:40
Delphi Grafiksachen und die VCL überhaupt sind jetzt nicht mein Mileu, aber einzelne Pixel zu manipulieren ist sicher ziemlich langsam. Falls du wirklich absolute Performance brauchst, gibt es bestimmt irgendwo eine Methode, wo man an ein Byte-Array kommt...

Ansonsten hat ein TCanvas doch sicher auch eine BeginUpdate() und EndUpdate()-Methode? Dazwischen sollte dann dein Zeichnen stattfinden...
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
1.882 Beiträge
 
Delphi 12 Athens
 
#3

AW: Gedimmten Hintergrund im Canvas schneller

  Alt 11. Jun 2013, 15:46
ja Scanline ist schneller...aber nicht so optimal.

Hm

Das schnellste ist wohl bitblt ot stretchblt mit bitmasken operationen
Am besten mit dwrop auf SRCPAINT

Zitat:
SRCPAINT Combines the colors of the source and destination rectangles by using the Boolean OR operator.
BITBLT hätte außerdem den vorteil das du nicht nur in das handel von einem canvas sondern auch z.b. in das händel ein Region kopieren kannst.
Eine Region kannst du dir in beliebiger Form bauen...
Du kannst aber auch z.t. eine Bitmap(schwarzweiß) als vorlage erzeugen so das nur die weißen oder schwarzen bereiche (je nach logische operation) von den kopier Operationen betroffen sind.

Wenn du nicht mit den GDI funktionen arbeiten willst
kannst du auch das nur unwesentlich langsamere
Tcanvas.copyrect
mit
Tcanvas.copymode
benutzen.
Andreas
Monads? Wtf are Monads?

Geändert von QuickAndDirty (11. Jun 2013 um 16:04 Uhr)
  Mit Zitat antworten Zitat
Nic2012

Registriert seit: 2. Mai 2012
62 Beiträge
 
#4

AW: Gedimmten Hintergrund im Canvas schneller

  Alt 11. Jun 2013, 18:25
Jo, mit Scanline geht das viel schneller, selbst im Designmodus kein Flackern mehr, Voraussetzung fürs Scanlinen ein temp. Bitmap:
Code:
procedure TExtShape.Paint;
  const
    Delta = 0.80;
  function ColorDimmed(Color: TColor): TColor;
  begin
    Color := ColorToRGB(Color);
    Result := RGB(Round(GetRValue(Color) * Delta),
                  Round(GetGValue(Color) * Delta),
                  Round(GetBValue(Color) * Delta));
  end;
type
  TRGB32 = packed record
    B, G, R, A: Byte;
  end;
  TRGB32Array = packed array[0..MaxInt div SizeOf(TRGB32)-1] of TRGB32;
  PRGB32Array = ^TRGB32Array;
var
  y, x: Integer;
  b: Graphics.TBitmap;
  Source: TRect;
  Dest: TRect;
  Row: PRGB32Array;
begin
  if FIsDimmed then begin

    b := Graphics.TBitmap.Create;
    try
      b.PixelFormat := pf32bit;
      b.Width := Width;
      b.Height := Height;

      Dest := Rect(0, 0, b.Width, b.Height);
      Source := Rect(0, 0, Width, Height);

      b.Canvas.CopyRect(Dest, Canvas, Source);

      for Y := 0 to Height -1 do begin
        Row := b.Scanline[Y];
        for X := 0 to Width -1 do begin
          Row^[X].R := Round(Row^[X].R * Delta);
          Row^[X].G := Round(Row^[X].G * Delta);
          Row^[X].B := Round(Row^[X].B * Delta);
        end;
      end;

      Canvas.CopyRect(Source, b.Canvas, Dest);

    finally
       b.Free;
    end;

    {
    for Y := 0 to Height -1 do
      for X := 0 to Width -1 do
        SetPixelV( Canvas.Handle, X, Y, ColorDimmed(GetPixel(Canvas.Handle, X, Y)));
    }
  end;

  inherited Paint;

  Canvas.Font := Font;
  Canvas.TextOut((Width - Canvas.TextWidth(Caption)) div 2, (Height - Canvas.TextHeight(Caption)) div 2, Caption);
end;
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Gedimmten Hintergrund im Canvas schneller

  Alt 5. Aug 2013, 11:02
Nachträglich fällt mir da noch ein, dass du Komponenten auch zeitweilig einfrieren kannst: Erst einfrieren, in Ruhe zeichnen, wieder auftauen. Das geht allerdings an der VCL vorbei direkt über die WinAPI:

Delphi-Quellcode:
SendMessage(myComponent.Handle, WM_SETREDRAW, 0, 0);
try
   [Gedöns]
finally
   SendMessage(myComponent.Handle, WM_SETREDRAW, 1, 0);
end;
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 10:20 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