Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Zwei transparente Bitmaps miteinader verrechnen (https://www.delphipraxis.net/192942-zwei-transparente-bitmaps-miteinader-verrechnen.html)

Harry Stahl 4. Jun 2017 12:44

Zwei transparente Bitmaps miteinader verrechnen
 
Ich krieg es leider nicht selbst hin.

Ausgangslage ist, dass ich zwei transparente Bitmaps habe und möchte das obere nun mit dem unteren Verrechnen.

Dabei interessiert mich nur der Fall, wo mindest ein Bitmap eine Transparenz hat.

Gegeben wären als

Delphi-Quellcode:
var
  Ru, GU, BU, AU: Byte; // für Farb- und Alphawert des unteren ( "U" für unten) Bitmaps.
  RO, GO, BO, AO: Byte; // für Farb- und Alphawert des oberen Bitmaps ("O" für oben)
  RN, GN, BN, AN: Byte; // für Farbe und Alphawert des Ergebnis-Bitmaps ("N" für neu)
begin
  // Werte für Variablen holen
  //...
  // Jetzt berechnen, aber wie?
 
  RN := ...
  GN := ...
  BN := ...
  AN := ...
end;
Jemand eine Idee oder einen Verweis auf eine schon bestehende Lösung?

EWeiss 4. Jun 2017 12:49

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Keine Ahnung was du genau willst..
Aber in meinen GDIClock projekt gibt es diese function.

procedure CombineImage(BackImg, OverlayImg: HBITMAP; LocX, LocY: Integer;
Transparent: Boolean);

EDIT:
Glaube das ist nicht das was du willst.
Verrechnen <> Kombinieren.
---------------
Auf jeden fall benötigst du ja erst mal die Farbwerte die sich in den jeweiligen Bitmaps befinden.
Dafür würde ich zu Anfangs das Handle (HBitmap) zu rate ziehen.

DibSection erstellen hbmReturn wäre dein HBitmap
mit Fillchar alles auf 0 setzen

Delphi-Quellcode:
FillChar(bm, sizeof(bm), 0);
Delphi-Quellcode:
      if GetObject(hbmReturn, sizeof(bm), @bm) <> 0 then
      begin
        pBits := bm.bmBits;
in pBits stehen dann alle Farbwerte bsp. des unteren Bitmaps
Wie man diese ausliest sollte dir bekannt sein.

Anschließen das gleiche bei den anderen, dann die Farbwerte miteinander vergleichen.. .wie auch immer.
Sollte nicht einfach sein vor allem wenn die Bitmaps unterschiedliche Ausmaße haben.
Das sollte man zumindest sicher stellen das sie gleich sind!

gruss

mensch72 4. Jun 2017 14:10

AW: Zwei transparente Bitmaps miteinader verrechnen
 
...ich gehe einfach mal davon aus, das die Werte für alle Pixel "wie und woher auch immer" verfügbar sind...


Teilen wir das Problem dann zunächst:
1. wir bestimmen die korrespondierende Transperenz für das Ergebinisbild
2. wir kombinieren die effektive Farbdeckung der 2 ihrerseits schon transparenten Bilder

- vereinfacht nehme ich jetzt mal als korrespondierende Transperenz den Durchschnitt der Einzeltransparenzwerte
- meine Berechnung funktioniert, wenn man Ax = 255 für 100% "volle Deckung", also null transparenz definiert
- jede Farbekomponente eines Pixels hat pro Ausgangsbild einen Wertebereich von 0..255, macht zusammen mit der Transparenz(Deckung 0..255) einen Wertebereich von 0.65535
- wir rechnen in gleich DWORD und im Wertebereich von 1.. und vermeiden so die Nullwerte und auch um so einfach mit dem vollen Wertebereich zu weiter zu rechnen(das ist der eigentliche und sehr einfache "Trick")

AN:=BYTE(DWORD((DWORD(AU)+DWORD(AO)) div 2));
RN:=BYTE(DWORD(((((DWORD(RU+1)*DWORD(AU+1))+(DWORD (RO+1)*DWORD(AO+1))) div 2) div (DWORD(AN)+1)) - 1));
GN:=BYTE(DWORD(((((DWORD(GU+1)*DWORD(AU+1))+(DWORD (GO+1)*DWORD(AO+1))) div 2) div (DWORD(AN)+1)) - 1));
BN:=BYTE(DWORD(((((DWORD(BU+1)*DWORD(AU+1))+(DWORD (BO+1)*DWORD(AO+1))) div 2) div (DWORD(AN)+1)) - 1));

Prkatische Erfahrung habe ich aber in der Nutzung einer ähnlichen Variante nur, wenn ich als Resultat ein NICHTTRANSPARENTES Bitmap berechne und für den aktzuellen Hintergrund die Pixel als als RH,GH,BH definiere... das ergibt dann dies:

AX:=BYTE(DWORD((DWORD(AU)+DWORD(AO)) div 2));
RN:=BYTE(DWORD((((DWORD(RU+1)*DWORD(AU+1))+(DWORD( RO+1)*DWORD(AO+1))+(DWORD(RH+1)*DWORD(AX+1))) div (3*256))-1));
GN:=BYTE(DWORD((((DWORD(GU+1)*DWORD(AU+1))+(DWORD( GO+1)*DWORD(AO+1))+(DWORD(GH+1)*DWORD(AX+1))) div (3*256))-1));
BN:=BYTE(DWORD((((DWORD(BU+1)*DWORD(AU+1))+(DWORD( BO+1)*DWORD(AO+1))+(DWORD(BH+1)*DWORD(AX+1))) div (3*256))-1));

(professionelle Varianten machen das wohl über/in einem anderem Farbmodell, weil es nach Farbenlehre wohl besser wäre Helligkeit und Farbe separat zu kombinieren)
Wenn ich mich bei den Klammern nicht verzählt habe und mein Gedächtnis stimmt, wird da bei beiden Varianten zumindest etwas mathematisch brauchbares herauskommen:)


ps:
ich weiß, das man wegen Punkt vor Strich ein paar Klammern sparen kann, aber wenn ich schon so unübersichtlich alles in eine Zeile schreibe, reicht mir so wenigstens für die Bearbeitungsfolge einfaches Klammerzählen ohne weitere Gehrinakrobatik;)

EWeiss 4. Jun 2017 14:30

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Da fehlt die Berechnung der Ausmaße der Bitmaps..
Wenn diese unterschiedlich sind.

gruss

mensch72 4. Jun 2017 16:41

AW: Zwei transparente Bitmaps miteinader verrechnen
 
nach Skalierung hat Harry nicht gefragt;)

Letztendlich skaliere man "wie auch immer" zuerst, so dass dann die "Overlayrechnung" quasi 1:1 geschieht... da es eh Pixelweise berechnet wird, kann man das auch in einem Schritt mit 2 äusseren Schleifen rechnen, wo man in "double" hochzählt, aber auf reale GanzzahlStep "pixelweise" X Y rückrundet und davon die Werte[x,y] .r .g .b .a , weil es ja nur ganze Pixel gibt:)

Harry Stahl 4. Jun 2017 17:20

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ja, mir geht es nicht um das ganze Bild, sondern nur der Part, wo beide Bilder Transparenzen haben, inwieweit die Bilder sich überlappen oder nicht, wird in der eigentlichen Funktion schon berücksichtigt.

Habe anliegend mal einen ganz ganz groben Auszug aus der Funktion für diese eine Stelle gemacht, und als Projekt angefügt.

Screenshot 1 zeigt im Bild links unten, wie Photoshop im Ergebnis die beiden oberen Bilder verrechnet (so hätte ich es auch gerne).
Im Bild rechts unten wird gezeigt, wie das Ergebnis meiner derzeitigen Routine aussieht. Man erkennt, dass die Überlagerungen der beiden roten Pinselstriche nicht OK ist (in der Mitte müsste sich ein tieferes Rot bilden, auch die Farbüberlagerungen der anderen Pinselstriche - grün und blau über rot - sind nicht 100% OK, die Grenzen sind zu scharf).

In Screenshot 2 habe ich mal den Vorschlag 1 von Mensch72 (vielen Dank dafür schon mal) umgesetzt, führt leider auch nicht zum korrekten Ergebnis (Vorschlag 2 hat eine krasse Farbverfälschung, da stimmt wohl etwas grundsätzlich nicht).

Anmerken möchte ich noch, dass ich die Transparenzen der Bitmaps, die ich aus dem TImage hole (sind dort in einem PNG-Format drin) mit einer Notlösung hier mal hergestellt habe, da gibt es eine leichte Farbverfälschung - etwas zu dunkel - (war aber die einzige Lösung, die mir auf die schnelle einfiel, ohne Dritt-Bibliotheken nutzen zu müssen).

Harry Stahl 4. Jun 2017 17:33

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Und damit man die Ergebnisse auch ohne die leichte Farbverfälschung ansehen kann, wenn ich meine Routine und die vorgeschlagene verwende, anliegend 2 Screenshots, Original in meinem Programm verwendet (Result3 von mir, Result4 von Mensch72).

mensch72 4. Jun 2017 17:44

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Ja, das entspricht meinen Erwartungen, speziell bei dem 2x "TeilRot" übereinander, wo Photoshop die Schnittmenge bei stimmiger Farbe "intensiver" darstellt, zeugt es davon das dort die Regeln für Farbmischung und Helligkeitsmischung der "Tranparenz" getrennt mit verschiedenen Regeln gerechnet wird... der einfache Durchschnitt zur Transparenzaddition scheint
noch nicht ganz optimal:)


ps:
- man püfe mal ob bei "DWORD(RO+1)" und RO=255 auch 256 raus kommt... das funktioniert nur, wenn RO erst von BYTE auf DWORD hoch gezogen wird und dann die eins addiert wird.
- ich habe das jetzt nur aus dem Gedächtnis getippt und es könnte sein das ich real da nochmal oder anders "geklammert" habe

Michael II 4. Jun 2017 18:18

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Hallo Harry Stahl

falls du dein "Alpha Bitmap A über B" selbst schreiben willst (wenn du's zum Beispiel für FMX und VCL nutzen willst, dann drängt sich das ja eventuell auf ;-)), dann kannst du Porter Duff verwenden:

https://de.wikipedia.org/wiki/Alpha_Blending

Irgendwo gibt's sicher bereits fertige Plattform unabhängige Beispiele für A über B. [Viele Dinge findest du auch im Source Code von Graphics32 u.a..]

Gruss
Michael

Harry Stahl 4. Jun 2017 18:50

AW: Zwei transparente Bitmaps miteinader verrechnen
 
Hallo Michael,

das hatte ich schon befürchtet, dass das ein wenig komplizierter sein wird und mit einer Formel endet, die mir Kopfschmerzen bereiten wird.

Aber jedenfalls Danke für den Tipp(:thumb:), was es nicht alles gibt. Jetzt muss ich also sehen, dass ich die Formel irgendwie auf die RGB-Zahlenwelt übertragen kann...


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:59 Uhr.
Seite 1 von 3  1 23      

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