Kurti: int alpha = (argb >> 24) & 0xff;

Hallo an alle Java Profis !
Mit folgenden Zeilen ändere ich alle nicht transparenten Pixel eines Bildes (BufferedImage) in schwarz.

for (int j = 0; j < image.getWidth(); j++) {
 for (int k = 0; k < image.getHeight(); k++) {
  // Lies die Farbwerte eines BufferedImage-Objekts und zerlege die Rueckgabe im Bereich des Alpha-Werts.
  int argb = image.getRGB(j, k);
  int alpha = (argb >> 24) & 0xff;
  // farbige Pixel schwarz setzen.
  if (alpha != 0) {
     image.setRGB(j, k, black);
  }
 }
}

Da ich das ganze aus der Insel habe, funktioniert es auch ;-)
Nur leider verstehe ich das ganze nicht so recht. Vor allem die Zeile:
  int alpha = (argb >> 24) & 0xff;
Für alle transparenten Farben wird eine 0 zurückgegeben. Warum? Und was wird zurückgegeben wenn das Pixel nicht transparent ist?

Danke schonmal,
Kurti

  1. Hallo Kurti,

    Für alle transparenten Farben wird eine 0 zurückgegeben. Warum? Und was wird zurückgegeben wenn das Pixel nicht transparent ist?

    Ich bin kein profi, aber ich würde raten, das die Bull für schwarz oder "black" steht...

    --
    Wo die Sprache aufhört, fängt die Musik an...
    ie:( fl:| br:^ va:| ls:/ fo:| rl:? n4:) ss:) de:] js:) ch:{ sh:) mo:) zu:)
  2. Yerf!

    Hallo an alle Java Profis !

    Ich bin zwar keiner, aber ich versuch mich trotzdem mal an einer Antwort, da es hier hauptsächlich um Bitoperationen geht.

    Nur leider verstehe ich das ganze nicht so recht. Vor allem die Zeile:
      int alpha = (argb >> 24) & 0xff;

    argb ist ein 32Bit Wert der die Farbe + Transparenz enthält
    Bitweise aufgeschlüsselt (a=transparenz, rgb=Farbkomponenten):

    aaaaaaaa rrrrrrrr gggggggg bbbbbbbb

    24 bedeutet eine verschiebung oder Rotation um 24 bit (bin mir jetzt nicht ganz sicher, ist aber hier egal)

    Verschiebung:
    00000000 00000000 00000000 aaaaaaaa

    Rotation:
    rrrrrrrr gggggggg bbbbbbbb aaaaaaaa

    Der bitweiese UND ( & 0xff) "filtert" nun (und ist eigenlich auch ein Hinweis, dass eine Rotation stattfindet ;-):

    0xFF:
    00000000 00000000 00000000 11111111

    Ergebnis:
    00000000 00000000 00000000 aaaaaaaa

    Für alle transparenten Farben wird eine 0 zurückgegeben. Warum? Und was wird zurückgegeben wenn das Pixel nicht transparent ist?

    Die Rückgabe ist der reine Transparenzwert des Pixels. Bei vollständiger Transparenz ist dieser 0, bei vollständiger Sichtbarkeit 255.

    Gruß,

    Harlequin

    --
    <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->
    1. Hallo Harlequin,

      24 bedeutet eine verschiebung oder Rotation um 24 bit (bin mir jetzt nicht ganz sicher, ist aber hier egal)

      Genau genommen weder das eine noch das andere, was dafür spricht, dass der Autor des Codes die genaue Semantik auch nicht kannte ;-)

      macht einen right-shift mit sign-extension, abhängig vom Vorzeichenbit wird also 0 oder 1 vorangestellt.

      Daher braucht man auch noch das & 0xFF, um evtl aufgefüllte Einsen wieder los zu werden. Hätte man den Operator >>> verwendet, der immer mit Null auffüllt, hätte man sich das sparen können.
      Man hätte natürlich auch gleich (color & 0xFF000000) != 0 nehmen können, womit man sich das Shiften spart, auch wenn es darauf natürlich nicht ankommt und es der Compiler möglicherweise wegoptimiert bekommt.

      Grüße

      Daniel

  3. Hallo,

    // Lies die Farbwerte eines BufferedImage-Objekts und zerlege die Rueckgabe im Bereich des Alpha-Werts.
      int argb = image.getRGB(j, k);
      int alpha = (argb >> 24) & 0xff;

    um es mal mit HTML zu -sagen-: <abbr title="A-lpha, R-ed, G-reen, B-lue">argb</abbr>

    Methode getRGB() gibt den Farbwert eines Bildpunktes der Koordinaten j*k aus. Aus stylesheet-Angaben ist sicher die hexadezimale Schreibweise für Farbwert (z. B. weiß: #ffffff) bekannt, wobei die ersten acht 8 für Rot, die zweiten acht 8 für Grün und die letzten 8 bit für Blau stehen. Das sind zusammen 24 Bit (24=8+8+8). Der Operator ">>" verschiebt diese Bit nun um 24 (Bit)Stellen nach rechts, sodaß aus 111111111111111111111111 letztendlich 000000000000000000000000 werden.

    Jedoch ist die Farbtiefe hier nicht 24 Bit sondern 32 Bit (8+8+8+8=32), denn es gibt ja nach den Alpha. Durch die Verschiebung (argb >> 24) werden also alle Bits der Farben Rot, Grün und Blau -weggeschmissen- und nur die Bits des Alpha bleiben übrig. Diese werden dann mit dem Operator "&" gegen 0xff geprüft (was meines Erachtens aber eigentlich wegfallen könnte, weil Variable alpha mit "int" angegeben ist, aber da bin ich mir nicht sicher, ob Java das mitmacht). D. h. alle noch im Ausdruck (argb >> 24) verbleibend gesetzten Bits werden in der Variable alpha gespeichert.

    // farbige Pixel schwarz setzen.
      if (alpha != 0) {

    Sind tatsächlich Bits nach der Verschiebung übrig geblieben, ist der integer Wert größer 0, was gleichbedeutend damit ist, das es kein transparenter / opazitärer Bildpunkt ist.

    image.setRGB(j, k, black);
      }

    Er wird also geschwärzt.

    Gruß aus Berlin!
    eddi

    --
    Der Verweis auf die Grundlagen Deines Handelns, ist das Joch zur Freiheit.
    Aber so gilt: Allen Leuten Recht getan, ist keine Kunst, weil's jeder kann.