Enrico: Dynamisch Koordinaten "poly" für Image Maps erstellen

Hallo,

ich habe mir eine eigene "Lightbox" zur vergrößerten Darstellung von kleinen Vorschaugrafiken erstellt.

Nun möchte ich das Auslösen der Lightbox aber nicht mehr über Anklicken der Vorschaubilder realisieren, d.h. inkl. auch transparenter Bereiche, was ich sehr unschön finde, sondern über verweissensitive Bereiche in Form von Image Maps "poly" umsetzen.

Bezüglich der Vorgehensweise müsste es wie folgt gehen:

  • Bild zeilenweise von oben nach unten durchlaufen (= 1. Koordinate) und daraus ein neues temporäres Bild definieren
  • Jedes temporäre Bild nun von links nach rechts durchlaufen und den ersten und letzten nicht-transparenten Pixel ermitteln (= 2. Koordinate)

Aktuell stecke ich im ersten Schritt fest:

function Bild_zerschneiden ($Bild)  
{  
   $Quelle        = imagecreatefrompng ($Bild);  
   $Quelle_Breite = imagesx ($Quelle);  
   $Quelle_Hoehe  = imagesy ($Quelle);  
  
   for ($Zeile = 0; $Zeile < $Quelle_Hoehe; $Zeile++)  
   {  
      $fn = sprintf ("img%02d.png", $Zeile);  
      $im = imagecreatetruecolor ($Quelle_Breite, 1);  
  
   // imagecopyresized ($Ziel, $Quelle, $ZielX, $ZielY, $QuelleX,       $QuelleY, $ZielW,         $ZielH, $QuelleW,       $QuelleH)  
      imagecopyresized ($im,   $Quelle, 0,      0,      $Quelle_Breite, $Zeile,   $Quelle_Breite, 1,      $Quelle_Breite, 1);  
  
      imagepng ($im, $fn);  
      imagedestroy ($im);  
   }  
}

Diese Funktion soll eine übergebene Grafik in jeweils 1px hohe temporäre zerschneiden.

Die Grafik wird korrekt übergeben, aber die temporären Grafiken werden nicht angezeigt.
Fehlermeldungen erhalte ich keine.

Wenn das Zerstückeln funktioniert, dann werde ich die jeweilige temporäre Grafik an eine weitere Funktion übergeben, die anhand transparenter Pixel die Koordinaten ermitteln wird.

Aber wie bereits beschrieben scheine ich im ersten Schritt noch irgendwo (einen) Fehler zu haben.

Woran kann es liegen, dass die temporären Grafiken nicht angezeigt werden?

Vielen Dank und Gruß,
Enrico

  1. Tach!

    Die Grafik wird korrekt übergeben, aber die temporären Grafiken werden nicht angezeigt.

    Wo sollen sie denn angezeigt werden? Und warum sprichst du im Plural? Ein PHP-Script(-Aufruf) kann in Richtung Browser immer nur ein Ding ausgeben, eine HTML-Seite oder eine Grafik oder ein anderes Ding.

    dedlfix.

    1. Hallo dedlfix,

      die ersten Gehversuche auf neuem Terrain sind immer wacklig...

      Wo sollen sie denn angezeigt werden?

      Heisst das im Umkehrschluss, dass das Zerschneiden, da ich ja keine Fehlermeldung(en) erhalte, funktioniert hat und damit fortfahren kann, die Koordinaten zu ermitteln?

      Gruß,
      Enrico

      1. Tach!

        Wo sollen sie denn angezeigt werden?
        Heisst das im Umkehrschluss, dass das Zerschneiden, da ich ja keine Fehlermeldung(en) erhalte, funktioniert hat und damit fortfahren kann, die Koordinaten zu ermitteln?

        Wenn du dir unsicher bist, dann lass das Ergebnis in eine Datei ausgeben und sieh sie dir in einem Bildbetrachtungsprogramm an. - Ich sehe gerade, das machst du ja schon, indem du imagepng() als zweiten Parameter einen Dateinamen angibst. Dabei kann natürlich nichts angezeigt werden.

        dedlfix.

        1. Hallo dedlfix,

          ok... Danke Dir, das hilft mir hoffentlich schon mal weiter.

          Ich geh jetzt schlafen, ich fang schon zum Schielen an... ^^

          "Morgen ist auch noch ein Tag"

          Gruß,
          Enrico

  2. hallo,

    lass uns nochmal alle teilhaben an deinem Vorhaben. Was genau willst du tun? Willst du einen Ausschnitt darstellen? Dann ist dein Ansatz nicht korrekt.

    1. Hallo Dachdecker,

      ich möchte den Umriss einer Grafik in Koordinaten ablegen, um daraus eine Imagemap "poly" zu erstellen.

      Dazu zerschneide ich zunächst eine übergebene Grafik vertikal in jeweils 1px hohe Einzelbilder.

      Danach durchlaufe ich jedes Einzelbild pixelweise von links nach rechts und ermittle jeweils den ersten und den letzten nichttransparenten Pixel.

      Da fällt mir gerade ein, dass ich mir das Zerschneiden auch sparen und statt dessen zwei Schleifen verwenden könnte:

      Eine, die von oben nach unten läuft und eine zweite, die von links nach rechts läuft...

      Gruß,
      Enrico

      1. Hallo,

        und so funktioniert es ohne Zerschneiden:

        $im = imagecreatefrompng ($Bild);  
          
        $width = imagesx($im);  
        $height = imagesy($im);  
          
        for ($i = 0; $i < $width; $i++)  
        {  
           for ($j = 0; $j < $height; $j++)  
           {  
              $rgba = imagecolorat ($im, $i, $j);  
              $color_tran = imagecolorsforindex ($im, $rgba);  
          
              if ($color_tran["alpha"] == 0)  
                 ...  
           }  
        }
        

        Gruß,
        Enrico

        1. Hallo,

          hmm, jetzt ist doch wieder ein Fehler aufgetaucht, es werden mir keine Koordinaten ausgegeben.

          Hier der Code:

          $Bild = imagecreatefrompng ("../GRAFIKEN/SORTIMENT/GewandungMuetzen3.png");  
            
          $Breite = imagesx ($Bild);  
          $Hoehe  = imagesy ($Bild);  
            
          $Halbes_Bild = round ($Breite / 2);  
            
          // Im ersten Durchlauf wird zunächst nur die rechte Bildhälfte durchlaufen  
          // Hier erhalte ich die rechten Koordinaten der Image Map  
            
          for ($x = $Halbes_Bild + 1; $x < $Breite; $x++)  
          {  
             for ($y = 0; $y < $Hoehe; $y++)  
             {  
                $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
                $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
            
                if ($x < $Breite - 1)  
                {  
                   $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
                   $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
                }  
                else  
                   $Farbe_naechster_Pixel = false;  
            
                if ($Farbe_aktueller_Pixel != 0 && $Farbe_naechster_Pixel !== false)  
                   echo $x . ", " . $y . "<br>";  
             }  
          }  
            
          // Im zweiten Durchlauf wird nun die linke Bildhälfte durchlaufen  
          // Hier erhalte ich die linken Koordinaten der Image Map  
            
          for ($x = 0; $x < $Halbes_Bild; $x++)  
          {  
             for ($y = 0; $y < $Hoehe; $y++)  
             {  
                $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
                $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
            
                $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
                $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
            
                if ($Farbe_aktueller_Pixel != 0)  
                   echo $x . ", " . $y . "<br>";  
                else  
                   if  ($Farbe_aktueller_Pixel == 0 && $Farbe_naechster_Pixel != 0)  
                      echo ($x + 1) . ", " . $y . "<br>";  
             }  
          }
          

          Wo liegt der Fehler?

          Danke und Gruß,
          Enrico

          1. Gerade sind mir noch Fehler in der ersten Schleife aufgefallen.

            Hier der korrigierte Code:

            $Bild = "../GRAFIKEN/SORTIMENT/GewandungMuetzen3.png";  
              
            Koordinaten_ermitteln ($Bild);  
              
            function Koordinaten_ermitteln ($Bild)  
            {  
               $Bild = imagecreatefrompng ($Bild);  
              
               $Breite = imagesx ($Bild);  
               $Hoehe  = imagesy ($Bild);  
              
               $Halbes_Bild = round ($Breite / 2);  
              
               for ($x = $Halbes_Bild + 1; $x < $Breite; $x++)  
               {  
                  for ($y = 0; $y < $Hoehe; $y++)  
                  {  
                     $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
                     $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
              
                     if ($x < $Breite - 1)  
                     {  
                        $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
                        $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
                     }  
                     else  
                        $Farbe_naechster_Pixel = false;  
              
                     if ($Farbe_aktueller_Pixel != 0 && ($Farbe_naechster_Pixel && $Farbe_naechster_Pixel == 0))  
                        echo $x . ", " . $y . "<br>";  
                  }  
               }  
              
               for ($x = 0; $x < $Halbes_Bild; $x++)  
               {  
                  for ($y = 0; $y < $Hoehe; $y++)  
                  {  
                     $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
                     $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
              
                     $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
                     $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
              
                     if ($Farbe_aktueller_Pixel != 0)  
                        echo $x . ", " . $y . "<br>";  
                     else  
                        if  ($Farbe_aktueller_Pixel == 0 && $Farbe_naechster_Pixel != 0)  
                           echo ($x + 1) . ", " . $y . "<br>";  
                  }  
               }  
            }
            
          2. Tach!

            hmm, jetzt ist doch wieder ein Fehler aufgetaucht, es werden mir keine Koordinaten ausgegeben.

            Deine Art, Fehler zu beschreiben, lässt noch sehr zu wünschen übrig. Als Programmierer müsstest du wissen, welche Programmzeile konkret wofür zuständig ist. Du beschreibst jedoch aus der Sicht der Anwender. Wenn du nun einen Fehler hast, muss es dir gelingen, diesen Fehler auf eine bestimmte Programmzeile einzugrenzen. Wo also erwartest du von deinem Code konkret welche Werte in Variablen oder von Funktionen zurückgegeben, und was erhältst du stattdessen? Bei Grafikerzeugung könnte man die Frage etwas abwandeln: Welcher Zwischenschritt bringt nicht das gewünschte Resultat im Ergebnis? Dazu wäre es günstig, alle Schritte zwischen dem Erstellen der leeren Grafik und dem Erzeugen des Ausgabeformats zunächst auszukommentieren und schrittweise freizugeben und den Erfolg zu kontrollieren. Alternativ lässt sich auch gleich so entwickeln: erst das Grundgerüst bauen (und testen) und dann die Einzelschritte einfügen und jeden auf Erfolg prüfen.

            dedlfix.

            1. Hallo dedlfix,

              Deine Art, Fehler zu beschreiben, lässt noch sehr zu wünschen übrig

              Sorry, war nicht in Ordnung von mir.

              Ich vermute die Ursache, warum keine Koordinaten ausgegeben werden, beim Durchlaufen der rechten Bildhälfte in der Abfrage

              if ($Farbe_aktueller_Pixel != 0 && ($Farbe_naechster_Pixel && $Farbe_naechster_Pixel == 0))  
                 echo $x . ", " . $y . "<br>";
              

              bzw. beim Durchlaufen der linken Bildhälfte in der Abfrage

              if  ($Farbe_aktueller_Pixel == 0 && $Farbe_naechster_Pixel != 0)  
                 echo ($x + 1) . ", " . $y . "<br>";
              

              Zum ersten Durchlauf:

              Ist die Farbe des aktuellen Pixels nicht transparent und (gibt es einen darauffolgenden Pixel und ist dieser transparent), dann gebe die Koordinaten aus.

              Zum zweiten Durchlauf (bezogen auf korrigierten Code):

              Ist die Farbe des aktuellen Pixels nicht transparent, dann gebe die Koordinaten aus.
              Anderenfalls gebe die Koordinaten des drauffolgenden Pixels aus, wenn die Farbe des aktuellen Pixels transparent und die Farbe des darauffolgenden Pixels nicht transparent ist.

              Da meine Grafiken nur außen transparent sind, müsste das funktionieren, was es aber nicht tut, es werden mir keine Koordinaten ausgegeben.

              Gruß,
              Enrico

              1. Tach!

                Ich vermute die Ursache, warum keine Koordinaten ausgegeben werden, [...]

                Nun, dann kommt jetzt die Phase, wo man die Vermutungen mit zum Beispiel Kontrollausgaben überprüft.

                dedlfix.

  3. Herrschaftszeiten, ich bin noch nicht ganz fit!

    Jetzt alles noch einmal von vorne:

    Ich möchte von einem übergebenen transparenten Bild den Umriss in Koordinatenform für eine Image Map "poly" ermitteln.

    Hier der Code:

    $Bild = "../GRAFIKEN/SORTIMENT/GewandungMuetzen3.png";  
      
    Koordinaten_ermitteln ($Bild);  
      
    function Koordinaten_ermitteln ($Bild)  
    {  
       $Grafik = $Bild;  
      
       echo '<map id="map' . preg_replace ("/[^0-9]/", "", $Bild) . '" name="map' . preg_replace ("/[^0-9]/", "", $Bild) . '">'  
             . '<area href="" shape="poly" coords="';  
      
       $Bild = imagecreatefrompng ($Bild);  
      
       $Breite = imagesx ($Bild);  
       $Hoehe  = imagesy ($Bild);  
      
       $Halbes_Bild = round ($Breite / 2);  
      
       for ($x = $Halbes_Bild + 1; $x < $Breite; $x++)  
       {  
          for ($y = 0; $y < $Hoehe; $y++)  
          {  
             $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
             $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
      
             if ($x < $Breite - 1)  
             {  
                $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
                $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
             }  
             else  
                $Farbe_naechster_Pixel = false;  
      
             if ($Farbe_aktueller_Pixel != 0 && ($Farbe_naechster_Pixel && $Farbe_naechster_Pixel == 0))  
                echo $x . ", " . $y;  
      
             if ($x < $Breite - 1)  
                echo ", ";  
          }  
       }  
      
       for ($x = 0; $x < $Halbes_Bild; $x++)  
       {  
          for ($y = 0; $y < $Hoehe; $y++)  
          {  
             $RGBA_aktueller_Pixel  = imagecolorat ($Bild, $x, $y);  
             $Farbe_aktueller_Pixel = $RGBA_aktueller_Pixel["alpha"];  
      
             $RGBA_naechster_Pixel  = imagecolorat ($Bild, $x + 1, $y);  
             $Farbe_naechster_Pixel = $RGBA_naechster_Pixel["alpha"];  
      
             if ($Farbe_aktueller_Pixel != 0)  
                echo $x . ", " . $y . "<br>";  
             else  
                if  ($Farbe_aktueller_Pixel == 0 && $Farbe_naechster_Pixel != 0)  
                   echo ($x + 1) . ", " . $y;  
      
             if ($x < $Halbes_Bild - 1)  
                echo ", ";  
          }  
       }  
      
       echo '">'  
       . '<img src="' . $Grafik . '" usemap="#map' . preg_replace ("/[^0-9]/", "", $Bild) . '">';  
    }
    

    Leider werden mir aber keine Koordinaten ausgegeben.

    Ich vermute die Ursache, warum keine Koordinaten ausgegeben werden, beim Durchlaufen der rechten Bildhälfte in der Abfrage

    if ($Farbe_aktueller_Pixel != 0 && ($Farbe_naechster_Pixel && $Farbe_naechster_Pixel == 0))  
       echo $x . ", " . $y;
    

    bzw. beim Durchlaufen der linken Bildhälfte in der Abfrage

    if ($Farbe_aktueller_Pixel != 0)  
       echo $x . ", " . $y;  
    else  
       if  ($Farbe_aktueller_Pixel == 0 && $Farbe_naechster_Pixel != 0)  
          echo ($x + 1) . ", " . $y . "<br>";
    

    Zum ersten Durchlauf:

    Ist die Farbe des aktuellen Pixels nicht transparent und (gibt es einen darauffolgenden Pixel und ist dieser transparent), dann gebe die Koordinaten aus.

    Zum zweiten Durchlauf (bezogen auf korrigierten Code):

    Ist die Farbe des aktuellen Pixels nicht transparent, dann gebe die Koordinaten aus.
    Anderenfalls gebe die Koordinaten des drauffolgenden Pixels aus, wenn die Farbe des aktuellen Pixels transparent und die Farbe des darauffolgenden Pixels nicht transparent ist.

    Da meine Grafiken nur außen transparent sind, müsste das funktionieren, was es aber nicht tut, es werden mir keine Koordinaten ausgegeben.

    Gruß,
    Enrico

    1. Hallo dedlfix,

      ich bin schon mittendrin und voll dabei :-)

      Gruß,
      Enrico

      1. Hallo,

        ich werde mein Vorhaben wieder verwerfen, da die Ermittlung nun funktioniert, die daraus resultierenden coords-Angaben aber sehr umfangreich sind und der an den Browser geschickten Code damit auch sehr aufgebläht wird.

        Danke euch trotzdem.

        Gruß,
        Enrico