Hintergrund-Transparent PNG imageMerge

ph1015

Mitglied
Hallo,

ich versuche gerade zwei Bilder (*.png) übereinander zu legen, so dass letztendlich draus ein Bild generiert wird. Soweit klappt es mit dem nachfolgenden Code eigentlich ganz gut:
Java:
 public boolean generate(Component comp) {
            MediaTracker mt;
            mt = new MediaTracker(comp);
            mt.addImage(i1, 1);
            mt.addImage(i2, 2);
            try { mt.waitForAll(); } catch (Exception ie) { }

            int wid1, wid2;
            int hgt1, hgt2;
            
            wid1 = i1.getWidth(comp);
            wid2 = i2.getWidth(comp);
            hgt1 = i1.getHeight(comp);
            hgt2 = i2.getHeight(comp);

            rwid = Math.max(wid1, wid2);
            rhgt = Math.max(hgt1, hgt2);

            results = new int[rwid * rhgt];

            int [] p1 = new int[rwid * rhgt];
            int [] p2 = new int[rwid * rhgt];

            PixelGrabber pg1 = new PixelGrabber(i1, 0, 0, wid1, hgt1, p1, 0, rwid);
            try { pg1.grabPixels(); } catch (Exception ie1) { }

            PixelGrabber pg2 = new PixelGrabber(i2, 0, 0, wid2, hgt2, p2, 0, rwid);
            try { pg2.grabPixels(); } catch (Exception ie2) { }

            cm = ColorModel.getRGBdefault();

            int y, x, rp, rpi;
            int red1, red2, redr;
            int green1, green2, greenr;
            int blue1, blue2, bluer;
            int alpha1, alpha2, alphar;
            double wgt1, wgt2;
            
            for(y = 0; y < rhgt; y++) {
                for(x = 0; x < rwid; x++) {
                	
                    rpi = y * rwid + x;
                    rp = 0;
                    blue1 = p1[rpi] & 0x00ff;
                    blue2 = p2[rpi] & 0x00ff;
                    green1 = (p1[rpi] >> 8) & 0x00ff;
                    green2 = (p2[rpi] >> 8) & 0x00ff;
                    red1 = (p1[rpi] >> 16) & 0x00ff;
                    red2 = (p2[rpi] >> 16) & 0x00ff;
                    alpha1 = (p1[rpi] >> 24) & 0x00ff;
                    alpha2 = (p2[rpi] >> 24) & 0x00ff;

                    wgt1 = w1 * (alpha1 / 255.0);
                    wgt2 = w2 * (alpha2 / 255.0);
                    
                    redr = (int)(red1 * wgt1 + red2 * wgt2);
                    redr = (redr < 0)?(0):((redr>255)?(255):(redr));
                    greenr = (int)(green1 * wgt1 + green2 * wgt2);
                    greenr = (greenr < 0)?(0):((greenr>255)?(255):(greenr));
                    bluer = (int)(blue1 * wgt1 + blue2 * wgt2);
                    bluer =  (bluer < 0)?(0):((bluer>255)?(255):(bluer));
                    alphar = 255;

                    rp = (((((alphar << 8) + (redr & 0x0ff)) << 8) + (greenr & 0x0ff)) << 8) + (bluer & 0x0ff);
                    
                    // save the pixel
                    results[rpi] = rp;
                }
            }
            return true;
        }
        public Image getGeneratedImage() {
            Image ret;
            MemoryImageSource mis;
            if (results == null) {
                Frame dummy = new Frame();
                generate(dummy);
                dummy.dispose();
            }
            mis = new MemoryImageSource(rwid, rhgt, cm, results, 0, rwid);
            ret = Toolkit.getDefaultToolkit().createImage(mis);
            return ret;
        }

Die PNG-Bilder haben allerdings einen transparenten Hintergrund (im IrfanView -> schwarz). Nun wird beim übereinanderlegen die Schwarze Farbe auch verwendet.

Wie kriege es hin, dass die Hintergrundfarbe 100%-ig transparent ist?

Gruß
Andy
 

AlexSpritze

Bekanntes Mitglied
Sieht das Ergebnisbild denn bis auf die Transparenz richtig aus?

Zeile 64 sieht für mich etwas seltsam aus. Auch hier vermute ich mal, dass anstatt der + Operatoren, | Operatoren angebrachter wären?
 

ph1015

Mitglied
Ja, das Ergebnisbild sieht ansonsten richtig aus.

Ich hatte es eben so getestet und das Ergebis ist gleich:
Java:
rp = (((((alphar << 8) | (redr & 0x0ff)) << 8) | (greenr & 0x0ff)) << 8) | (bluer & 0x0ff);

Gruß
Andy
 

Michael...

Top Contributor
Ich hätte erst einmal versucht ein BufferedImage passender Größe und vom Typ TYPE_INT_ARGB zu erstellen. Dann per createGraphics() das Graphics Objekt des Images holen und die zwei Bilder mittels drawImage(...) draufmalen und abspeichern.
 

ph1015

Mitglied
@Michael...: Es hört sich gut an. Das werde ich mal bei Gelegenheit nachverfolgen.

@AlexSpritze: Wie kann ich es den an der Stelle anders machen?
 

AlexSpritze

Bekanntes Mitglied
@AlexSpritze: Wie kann ich es den an der Stelle anders machen?

Du könntest den Alpha-Wert alphar genauso wie z.B. den bluer-Wert gewichtet aus den beiden Ausgangsbildern bestimmen. Oder eben wenn beide Alpha-Werte gleich null sind dann auch auch alphar auf null setzen, damit im Endbild die komplette Transparenz zu sehen ist. Also laut dem Link von mir, ist 255 keine Transparenz und 0 wäre volle Transparenz.
 

ph1015

Mitglied
Ja, das sieht schon besser aus. ich habe alphar wie folgt gesetzt:

Java:
alphar = (int)(alpha1 * wgt1 + alpha2 * wgt2);
alphar =  (alphar < 0)?(0):((alphar>255)?(255):(alphar));

Leider stimmt die Farbe im Ergebnisbild nicht genau. Im Anhang habe ich ein Screeenshot gemacht.

Hast du vl. noch eine Idee wie ich es hinkriege, dass auch die Farbe im Ergebnisbild einigermaßen stimmt?
 

Anhänge

  • 1.jpg
    1.jpg
    1,2 KB · Aufrufe: 22
  • 2.jpg
    2.jpg
    1,2 KB · Aufrufe: 26
  • 1und2.jpg
    1und2.jpg
    1,4 KB · Aufrufe: 25

AlexSpritze

Bekanntes Mitglied
Irgendwie gewichtest du ja die Pixel aus beiden Bildern abhängig vom Alpha. Vielleicht wäre es einfacher, du würdest sagen Bild1 ist oberhalb von Bild2 und wenn du an einem nichttransparenten Pixel von Bild1 bist, übernimmst du diesen Pixel, ansonsten nimmst du den Pixel von Bild2, und als letzte Möglichkeit ist der Pixel eben transparent im Ergebnisbild.

Oder möchtest du explizit beide Bilder vermischen, wenn sie an gleichen Orten sichtbare Informationen haben?

PS: Wo kommen die Werte w1 und w2 in Zeile 53 und 54 her?
 

ph1015

Mitglied
Ich möchte eigentlich das Bild2 über das Bild1 legen, sodass das Bild1 von dem Bild2 überdeckt wird.

w1 und w2 sind fest definiert und zwar wie folgt:
Java:
double w1 = 0.5;
double w2 = 0.5;
 

ph1015

Mitglied
ach ja stimmt, daran habe ich gar nicht gedacht. Danke! Nun sieht es gut aus bzw. es sieht so aus wie ich es haben möchte!

Ich habe die Werte w1 und w2 auf 1 gesetzt.

:toll:
Gruß
Andy
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Jemand einen Tipp wie man ein Javafx-Hintergrund "dynamisch" macht Allgemeine Java-Themen 3
B Login für User, der im Hintergrund Schedules ausführt Allgemeine Java-Themen 16
G BlueJ Hintergrund Allgemeine Java-Themen 10
Aruetiise LayoutManager JButton in den Hintergrund Allgemeine Java-Themen 7
I Programm im Hintergrund bei Windows zur Steuerung der Tastatur nutzen Allgemeine Java-Themen 2
S Allgemeine parallelisierte Loesung um Daten im Hintergrund zu laden..? Allgemeine Java-Themen 6
x22 Hintergrund in Netbeans ändern Allgemeine Java-Themen 3
E Hintergrund einer JTable änden Allgemeine Java-Themen 2
J Java-Programm im Hintergrund Allgemeine Java-Themen 3
C Programm das im Hintergrund läuft Allgemeine Java-Themen 2
L Problem mit Hintergrund bei JAVA Applet Allgemeine Java-Themen 27
S BufferedImage mit Transparenten Hintergrund Allgemeine Java-Themen 4
F JFrame zeigt Hintergrund und nicht den Inhalt Allgemeine Java-Themen 12
M Hintergrund bei meiner Uhr Allgemeine Java-Themen 7
F Programm im Hintergrund Allgemeine Java-Themen 8
G java Programm im Hintergrund laufen lassen Allgemeine Java-Themen 8
M Threads starten und im Hintergrund ablaufen lassen Allgemeine Java-Themen 11
K Bildschirm Hintergrund ändern Allgemeine Java-Themen 19
S Java Programm soll im Hintergrund laufen (vgl. fork() bei C) Allgemeine Java-Themen 10
J JDialog Bild als Hintergrund Allgemeine Java-Themen 19
E Methoden im Hintergrund ausführern Allgemeine Java-Themen 5
J Wie mache ich den Hintergrund einer Image durchsichtig? Allgemeine Java-Themen 7
B Hintergrund bei Swing Allgemeine Java-Themen 6
P Gif transparent machen Allgemeine Java-Themen 2
A BufferedImage einzelne Pixel transparent machen V2.0 Allgemeine Java-Themen 2
V 2D-Grafik Bild transparent machen. Allgemeine Java-Themen 4
M Farbe transparent machen Allgemeine Java-Themen 3
L JPanel(bzw.) Panels transparent machen Allgemeine Java-Themen 7
L Buttons unsichtbar, Transparent Allgemeine Java-Themen 6
U Transparent Buttons - unterschiedliche Java-Versionen Allgemeine Java-Themen 8

Ähnliche Java Themen


Oben