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
Benutzerbild von Harry Stahl
Harry Stahl

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

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 17: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).
Angehängte Grafiken
Dateityp: png Result3.png (195,0 KB, 23x aufgerufen)
Dateityp: png Result4.png (217,0 KB, 25x aufgerufen)
  Mit Zitat antworten Zitat
mensch72

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

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 17: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 17:56 Uhr)
  Mit Zitat antworten Zitat
Michael II

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

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 18: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 18:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

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

AW: Zwei transparente Bitmaps miteinader verrechnen

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

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.199 Beiträge
 
Delphi 12 Athens
 
#5

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:31
Es gibt ja mindestens zwei Varianten wie man sowas verrechnet.

* Entweder die Bilder zu 50:50 vemischen, also als wenn man zwei "flüssige" Farben zusammen schüttet.
Das ergibt praktisch ganz billig 'nen Mittelwert und es ist egal was oben oder unten ist
x := (x + y) / 2
Die Transparent natürlich umgekehrt
x := 255 - ((255 - x) + (255 - y)) / 2

* Oder man macht es richtig, so als wenn man zwei bemalte Glasscheiben übereinander legt
die Gesamttransparenz zusammenrechnen (transparenz-unten * trasparenz-oben ... 50% * 50% = 25%)
und bei den Farben die Transparenz des oberen Bildes nehmen, damit den eigenen Farbanteil berechnen (255 - tansparenz)
dann den Farbanteil mit der Transparenz des unteren Bildes (ebenfalls 255 - tansparenz)
dann nochmal von unten den oben durchscheinenden Teil (tansparenz ... also (255 - transparenz-unten) * trasparenz-oben)
und zum Schluß beide Farben addieren



und egal was du tust, du mußt immer auf Überläufe achten, sonst gibt es solche "Farbverfälschungen", wo z.B. aus zwei Mal fast 0% plötzlich 100% Transparenz entsteht
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
mensch72

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

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:44
also gilt:

AN:=255-BYTE(DWORD( (DWORD(AU)*DWORD(AO)) div (DWORD(AU)+DWORD(AO)) ));

Gemäß Beispiel
50% & 50% -> 25% ...
(128*128) / (128+128) -> 64 was ja 25% entspricht
  Mit Zitat antworten Zitat
Michael II

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

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:41
Hallo Harry

die Formel darf dich nicht abschrecken. Du musst eigentlich nur zwei Dinge tun für jedes Pixel:

1. Den neuen Alphawert berechnen
2. Die neuen Farbwerte für R,G,B.

Ich hab's rasch getan und das Resultat sieht wirklich gut aus.

In diesem Beispiel siehst du, wie du es für zwei gleich grosse Bitmaps A, B tun kannst, welche direkt übereinander gelegt werden.
( Du willst dann natürlich Code schreiben für A an Position x, y über B legen oder ähnlich. )

Delphi-Quellcode:
procedure AueberB( a, b, c : TBitMap );

var lineA, lineB, lineC : PRGB32Array;
    x, y : integer;
    alphaA, alphaB, alphaC : extended;
begin
  a.PixelFormat := pf32Bit;
  b.PixelFormat := pf32Bit;
  c.PixelFormat := pf32bit;

  for y := 0 to a.Height-1 do
  begin
    lineA := a.ScanLine[y];
    lineB := b.ScanLine[y];
    lineC := c.ScanLine[y];

    for x := 0 to a.Width-1 do
    begin
       // Test
      (* lineA[x].A := 255;
      lineB[x].A := 0; *)

      alphaA := lineA[x].A/255;
      alphaB := lineB[x].A/255;
      // 0 = Transparent - 1 = instransparent
      alphaC := alphaA + ( 1 - alphaA )*alphaB; // (den Fall alphaA=0 UND alphaB=0 musst du hier noch sep. behandeln)
      lineC[x].A := round(alphaC*255);
      lineC[x].R := round(1/alphaC*(alphaA*lineA[x].R + (1-alphaA)*alphaB*lineB[x].R ));
      lineC[x].G := round(1/alphaC*(alphaA*lineA[x].G + (1-alphaA)*alphaB*lineB[x].G ));
      lineC[x].B := round(1/alphaC*(alphaA*lineA[x].B + (1-alphaA)*alphaB*lineB[x].B ));
    end;
  end;

end;

Testen:
So rufe ich die Prozedur auf:
Ich lade in diesem Beispiel in A und B das gleiche Bild, in A um 10,10 versetzt.
Ins Bild A schreibe ich den Buchstaben 'A' rein, ins Bild B den Buchstaben 'B'. (Damit sehe ich im Resultatbild C in etwa, wie A und B zum Resultat C beitragen.)

In der Prozedur AueberB (siehe Code oben) habe ich zwei Zeilen
lineA[x].A := 255;
lineB[x].A := 0;
"auskommentiert". Dort kannst du globale Alpha-Werte setzen und sehen, wie sich diese Werte aufs Resultatbitmap C auswirken.


Delphi-Quellcode:
procedure TForm100.Button1Click(Sender: TObject);
var a,b,c : TBitMap;
begin
  a := TBitMap.Create;
  b := TBitMap.Create;
  c := TBitMap.Create;

  a.LoadFromFile( 'C:\Users\Michael\Desktop\thun.bmp' );
  b.LoadFromFile( 'C:\Users\Michael\Desktop\thun.bmp' );
  a.Canvas.Draw( 10,10,b );

  a.Canvas.Font.Size := 100;
  a.Canvas.TextOut( 10,10, 'A' );
  b.Canvas.Font.Size := 100;
  b.Canvas.TextOut( 10,210, 'B' );
  c.SetSize( a.Width, a.Height );

  AueberB( a, b, c );

  c.SaveToFile( 'C:\Users\Michael\Desktop\thun2.bmp');

  a.Free;
  b.Free;
  c.Free;
end;

Natürlich kann man die ganze Sache auch in den "Integer Bereich" verlegen. Bei modernen Prozessoren gewinnt man aber (leider ) häufig gar nicht mehr viel Zeit; auf älteren Kisten jedoch sehr...
Michael Gasser

Geändert von Michael II ( 4. Jun 2017 um 20:41 Uhr)
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
670 Beiträge
 
#8

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 19:48
Graphhics32?
https://github.com/graphics32/graphi...g/TextureBlend
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.199 Beiträge
 
Delphi 12 Athens
 
#9

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 4. Jun 2017, 20:20
Da, wo die zwei Bilder nicht übereinander liegen, dann kann man da für das "fehlende" Bild als Bummywert ein Pixel mit 100% Transparenz verwenden und damit weiterrechen.

Nach Wegkürzen aller Parameter bleibt dann das Pixel des anderen Bildes 1:1 übrig.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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 18:04 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