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.561 Beiträge
 
Delphi 12 Athens
 
#1

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
44.549 Beiträge
 
Delphi 12 Athens
 
#2

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
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
mensch72

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

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
778 Beiträge
 
Delphi 11 Alexandria
 
#4

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
674 Beiträge
 
#5

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
44.549 Beiträge
 
Delphi 12 Athens
 
#6

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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#7

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 5. Jun 2017, 00:27
So, danke erst mal für die Hinweise und die erste Umsetzung der Formel.

Habe daran noch ein wenig weiter gearbeitet, das sieht nun so aus:

Delphi-Quellcode:
  alphaA := A/255;
  alphaB := AO/255;
  alphaC := alphaA + (1 - alphaA )* AlphaB;

  R := round((1/alphaC) * (alphaA* (R/255) + (1-alphaA) * alphaB * (Ro/255) ) * 255);
  G := round((1/alphaC) * (alphaA* (G/255) + (1-alphaA) * alphaB * (Go/255) ) * 255);
  B := round((1/alphaC) * (alphaA* (B/255) + (1-alphaA) * alphaB * (Bo/255) ) * 255);

  A := round (AlphaC * 255);
Funktioniert soweit, nur ist die Verrechnung der Farben anscheinend noch nicht ausreichend. Daher habe ich das hier noch mit meiner Ursprungslösung ergänzt:

Delphi-Quellcode:
  alphaA := A/255;
  alphaB := AO/255;
  alphaC := alphaA + (1 - alphaA )* AlphaB;

  B := (ao * (bo - b) shr 8 + b); // hier ergänzt
  G := (ao * (go - g) shr 8 + g); //
  r := (ao * (ro - r) shr 8 + r); //

  R := round((1/alphaC) * (alphaA* (R/255) + (1-alphaA) * alphaB * (Ro/255) ) * 255);
  G := round((1/alphaC) * (alphaA* (G/255) + (1-alphaA) * alphaB * (Go/255) ) * 255);
  B := round((1/alphaC) * (alphaA* (B/255) + (1-alphaA) * alphaB * (Bo/255) ) * 255);

  A := round (AlphaC * 255);
Mit dieser Ergänzung wird das Ergebnis exakt so angezeigt, wie Photoshop die Datei errechnet.

Anliegend mal ein Screenshot, wo eine PSP-Layer-Datei auf eine Ebene reduziert wurde und als PNG-Datei geladen (linke Seite).
Rechts daneben die Original-PSP-Datei, mit den geladenen Layern, wo das Ergebnis dann berechnet mit der o.g. Routine im Programm angezeigt wird (rechte Seite).
Angehängte Grafiken
Dateityp: png result-ok.png (96,0 KB, 42x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 5. Jun 2017, 12:50
Beeindruckend
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#9

AW: Zwei transparente Bitmaps miteinader verrechnen

  Alt 5. Jun 2017, 13:42
@Stahli

Danke, aber das Kompliment geht an all die netten Kollegen, die mir hier geholfen haben, alleine hätte ich das nicht hinbekommen.
Hatte zuvor bestimmt einen halben Tag lang versucht, das selbst zu backen, aber ohne Erfolg.

Da sieht man mal wieder, wie super hilfreich und unverzichtbar dieses Forum ist (insofern mal ein herzliches Danke an Daniel und die anderen Forenunterstützer)!
  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 19:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz