Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#38

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 23. Feb 2016, 22:16
Hmm, ich glaube da ist dann dein interner Aufbau im Nachgang dafür etwas ungünstig ausgelegt. In meinem Kopf stellte sich die Struktur ganz grob so dar:
Delphi-Quellcode:
type
  TMyLayeredImage = class;

  TMyLayer = class
  public
    procedure Changed; // Führt Prüfung aus und setzt FHasTransparency und FChanged in der folgenden Image-Klasse (Es muss hierfür eine Owner-Beziehung geben, daher die Forward-Deklaration)
    property BMP: TBitmap read FBMP;
    property HasTransparency: Boolean read FHasTransparency;
    property Bounds: TRect read GetBounds write SetBounds; // SetBounds würde Changed im Owner auslösen, nicht aber eine Prüfung für den Layer selbst
  end;

  TMyLayeredImage = class
  private
    FImage: TBitmap; // Container für das fertige Bild
    FLayers: TObjectlist; // Beinhaltet die TMyLayer-Instanzen, Index 0 ist die unterste
    procedure Compose; // Fügt die Layer in FImage zusammen
  public
    property Image: TBitmap read GetImage; // In GetImage() dann "if FChanged then Compose; result := FImage;"
    // Und dann noch so nette Helfer (Komfortfunktionen halt) wie:
    property LayerAtPoint[x, y: Integer]: TMyLayer read GetLayerAtPoint; // Gibt den obersten Layer zurück, der den Punkt (x,y) beinhaltet, oder nil bei keinem
  end;
Wie gesagt ganz ganz grob. Jedes Layer würde einfach sein Transparenz-Bit mitführen, jede Operation auf dem Layer löst das Changed Ereignis aus, welches auch an den Owner (die zusammenfügende LayeredImage Klasse) gereicht wird. Beim Zeichnen wird dann einfach das fertige Image angefordert, und allen am Bild beteiligten ist klar ob überhaupt neu Komponiert werden muss, und welche Layer zu diesem Zeitpunkt Transparenzen haben.
Ob sich sowas jetzt noch überhaupt in deine Struktur hineinfiedel lässt kann ich natürlich nicht beurteilen. Aber das wäre in etwa mein erste Gedanke wenn ich an ein Layered-Image gehen würde. Die Prüf-Routine würde lediglich nur in genau den gerade geänderten Layern gebraucht.

Letztlich würde ich aber, wenn so etwas anstünde, direkt zur GR32 greifen und die einfach immer stumpf alles zeichnen lassen - weil das ist schnell genug, wenn man nicht gerade mehrere hundert Layer in 12 Megapixel hat. (Dafür gäbe es aber auch eigentlich schon keine performante Lösung mehr, egal wie. Speicher wird dann auch schnell rare Ware.)


@Rollo62:
Gehen würde das mit der GPU, und sogar sehr flott. Aber du hast ein Problem dabei bereits bemerkt: Es bringt kaum etwas, wenn man NUR diese Funktion in der GPU machen würde, da man stets alle Daten immer hin und her schaufeln müsste. (Ein Sharing gibt es nicht.) Zwar geht das meist schon irre schnell, gemessen an den Mengen, aber der Gewinn steht dem Mehraufwand fast nur dann in gutem Verhältnis gegenüber, wenn man praktisch alles über die GPU macht.
Mittlerweile ist das sogar viel viel einfacher als früher. Zu Zeiten von DirectX 9 und so musste man Pixel-Shader bemühen, und recht fummelig ein Quasi-3D Programm bauen um das von hinten durch die Brust zweckzuentfremden. Dank CUDA und OpenCL stehen hier mittlerweile aber Werkzeuge zur Verfügung, bei denen man sich um die Herkunft der GPU als reinen 3D- und Shader-Knecht nicht mehr scheren muss, und sie wie einen echten Vektorprozessor ansprechen kann. Leider weiss ich nicht wie es um Implementierungen der beiden großen APIs für Delphi steht. Und man muss sich an eine doch sehr andere Art der Programmierung gewöhnen, als man sie von Delphi im Alltag gewohnt ist.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat