AGB  ·  Datenschutz  ·  Impressum  







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

Zwei transparente Bitmaps miteinader verrechnen

Ein Thema von Harry Stahl · begonnen am 4. Jun 2017 · letzter Beitrag vom 9. Jun 2017
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#1

Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 13:44
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?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 13:49
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

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

Geändert von EWeiss ( 4. Jun 2017 um 14:42 Uhr)
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#3

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 15:10
...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

Geändert von mensch72 ( 4. Jun 2017 um 15:16 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 15:30
Da fehlt die Berechnung der Ausmaße der Bitmaps..
Wenn diese unterschiedlich sind.

gruss
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#5

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 17:41
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
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 18:20
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).
Miniaturansicht angehängter Grafiken
result1.jpg   result2.jpg  
Angehängte Dateien
Dateityp: zip ImgMix.zip (832,0 KB, 8x aufgerufen)

Geändert von Harry Stahl ( 4. Jun 2017 um 18:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 18:33
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).
Miniaturansicht angehängter Grafiken
result3.png   result4.png  
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#8

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 18:44
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

Geändert von mensch72 ( 4. Jun 2017 um 18:56 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:18
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
Michael Gasser

Geändert von Michael II ( 4. Jun 2017 um 19:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:50
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(), was es nicht alles gibt. Jetzt muss ich also sehen, dass ich die Formel irgendwie auf die RGB-Zahlenwelt übertragen kann...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 16:02 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