TeraVolt: Probleme bei Grafikerzeugung mit PHP

Hallo und Guten Tag,

bin gerade dabei mich in PHP einzuarbeiten und jetzt kommen halt die Probleme.

Habe dieses einfache Script zur Ausgabe einer halben Ellipse ausprobiert:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <head>
  <title>Halbe Ellipse mit PHP</title>
 </head>
 <body>
  <p>hier noch HTML</p>
  <?php
   $image = ImageCreate(300,200);
   $farbe_body = ImageColorAllocate($image,243,243,243);
   $farbe_ellipse = ImageColorAllocate($image,10,36,106);
   ImageArc($image,150,60,200,100,0,180,$farbe_ellipse);
   Header("Content-type: image/png");
   ImagePNG($image);
  ?>
 </body>
</html>

und erhalte nur den Ersatztext "Die Grafik "http://localhost/test/test02.php" kann nicht angezeigt werden, weil sie Fehler enthält." Sowohl local als auch auf dem webspace. Auch die Ausgabe des "html" textes unterbleibt.
phpinfo() gibt für den GD Support und für PNG "enabled" und als Version 2.0.22 an. Daran sollte es also doch nicht scheitern oder?

Nach unendlichen rumprobieren habe ich festgestellt, wenn man alles was nicht zum script gehört weglässt und <?php in der ersten Zeile steht, ohne sonstige Zeichen oder Leerzeichen dazwischen, dann zeigt der Brausär die Grafik an.

Was mache ich bloß flasch?

Danke schon mal im voraus,
TeraVolt

  1. Hallo,

    bin gerade dabei mich in PHP einzuarbeiten ...

    und dann gleich die anspruchsvollen Themen wie Grafiken generieren? oh oh...

    [...]
      <p>hier noch HTML</p>
      <?php
       $image = ImageCreate(300,200);
       $farbe_body = ImageColorAllocate($image,243,243,243);
       $farbe_ellipse = ImageColorAllocate($image,10,36,106);
       ImageArc($image,150,60,200,100,0,180,$farbe_ellipse);
       Header("Content-type: image/png");
       ImagePNG($image);
      ?>
    </body>
    </html>

    und erhalte nur den Ersatztext "Die Grafik "http://localhost/test/test02.php" kann nicht angezeigt werden, weil sie Fehler enthält."

    Logisch. Was passiert denn hier aus Browsersicht: Da kommen Daten vom Server angerauscht, vornedran ein Header, der da sagt, es sei ein PNG-Bild. Dann kommt aber erst ein bissel HTML-Gedöns, mit dem er unter diesen Voraussetzungen gar nicht rechnet, was auch innerhalb der Bilddaten nichts verloren hat. Der Browser weiß ja nicht, dass die "richtigen" Bilddaten irgendwo etliche Bytes später anfangen.
    Du hast das Grundprinzip offensichtlich nicht richtig verstanden.

    Auch wenn du Bilder mit PHP erzeugst, bleiben die HTML- und die Bildressourcen immer noch sauber getrennt wie bei rein statischen Inhalten. Das heißt, du hast ein Dokument, das den HTML-Quellcode liefert (der _kann_ auch durch ein Script generiert sein), und du hast eine Bildressource.
    Das Script, das die Bilddaten generiert, darf dann aber wirklich _nur_ Bilddaten ausgeben, sonst absolut nichts. Die Ausgabe des Scripts muss also identisch mit den Binärdaten des gewünschten Bildes sein. Zusätzlicher HTML-Code hat da nichts verloren. Du musst also deine Daten trennen, etwa so:

    (1) HTML-Quellcode
     --8<----
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
     <head>
      <title>Halbe Ellipse mit PHP</title>
     </head>
     <body>
      <p>hier noch HTML</p>
      <img src="bild.php" alt="dynamisch generiertes bild">"
     </body>
    </html>
     --8<----

    (2) PHP-Grafikscript (hier z.B. bild.php)
     --8<----
      <?php
       $image = ImageCreate(300,200);
       $farbe_body = ImageColorAllocate($image,243,243,243);
       $farbe_ellipse = ImageColorAllocate($image,10,36,106);
       ImageArc($image,150,60,200,100,0,180,$farbe_ellipse);
       header("Content-type: image/png");
       ImagePNG($image);
      ?>
     --8<----

    Achte darauf, dass in deinem Script außerhalb des <?php ... ?> Blocks _nichts_ mehr steht, also auch kein Leerzeichen! Denn diese Zeichen würden ja unverändert mit an den Browser gesendet und so das generierte Bild verfälschen.

    phpinfo() gibt für den GD Support und für PNG "enabled" und als Version 2.0.22 an. Daran sollte es also doch nicht scheitern oder?

    Nein, wenn man es richtig macht, eigentlich nicht. ;-)

    Nach unendlichen rumprobieren habe ich festgestellt, wenn man alles was nicht zum script gehört weglässt und <?php in der ersten Zeile steht, ohne sonstige Zeichen oder Leerzeichen dazwischen, dann zeigt der Brausär die Grafik an.

    Bingo. Das ist es, was ich eben meinte.
    Schönen Sonntag noch,

    Martin

    --
    Viele Fachleute vertreten die Ansicht, jedes Feature eines Programms, das sich nicht auf Wunsch abstellen lässt, sei ein Bug.
    Außer bei Microsoft. Da ist es umgekehrt.
    1. Hallo Martin,

      und dann gleich die anspruchsvollen Themen wie Grafiken generieren? oh oh...

      noja, hat mich halt gerade interessiert...

      Logisch. Was passiert denn hier aus Browsersicht: Da kommen Daten vom Server angerauscht, vornedran ein Header, der da sagt, es sei ein PNG-Bild. Dann kommt aber erst ein bissel HTML-Gedöns, mit dem er unter diesen Voraussetzungen gar nicht rechnet, was auch innerhalb der Bilddaten nichts verloren hat. Der Browser weiß ja nicht, dass die "richtigen" Bilddaten irgendwo etliche Bytes später anfangen.

      Hatte gemeint, dass die Zeile mit dem 'Header("Content-type: image/png");'
      eben erst dann abgearbeitet wird wenn sie an der Reihe ist. Das war also flasch!

      Du hast das Grundprinzip offensichtlich nicht richtig verstanden.

      Jetzt wo du es sagst, ist es mir einigermassen klar.

      Auch wenn du Bilder mit PHP erzeugst, bleiben die HTML- und die Bildressourcen immer noch sauber getrennt wie bei rein statischen Inhalten. Das heißt, du hast ein Dokument, das den HTML-Quellcode liefert (der _kann_ auch durch ein Script generiert sein), und du hast eine Bildressource.

      Mannnnnnn *vornKopfklatsch* hey warum schreibt der Verfasser von "PHP5 Praxis und Referenz" das nicht so in sein Buch rein.

      Das Script, das die Bilddaten generiert, darf dann aber wirklich _nur_ Bilddaten ausgeben, sonst absolut nichts. Die Ausgabe des Scripts muss also identisch mit den Binärdaten des gewünschten Bildes sein. Zusätzlicher HTML-Code hat da nichts verloren. Du musst also deine Daten trennen, etwa so:

      (1) HTML-Quellcode
      --8<----
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
      <html>
      <head>
        <title>Halbe Ellipse mit PHP</title>
      </head>
      <body>
        <p>hier noch HTML</p>
        <img src="bild.php" alt="dynamisch generiertes bild">"
      </body>
      </html>
      --8<----

      (2) PHP-Grafikscript (hier z.B. bild.php)
      --8<----
        <?php
         $image = ImageCreate(300,200);
         $farbe_body = ImageColorAllocate($image,243,243,243);
         $farbe_ellipse = ImageColorAllocate($image,10,36,106);
         ImageArc($image,150,60,200,100,0,180,$farbe_ellipse);
         header("Content-type: image/png");
         ImagePNG($image);
        ?>
      --8<----

      Jau SUUUUUUPER genau so geht es - *freufreufreu*

      Achte darauf, dass in deinem Script außerhalb des <?php ... ?> Blocks _nichts_ mehr steht, also auch kein Leerzeichen! Denn diese Zeichen würden ja unverändert mit an den Browser gesendet und so das generierte Bild verfälschen.

      Hab ich schon gemerkt, es darf absolut nix anderes, kein return und kein space drinsein. Latürnich auch kein echo und so'n Zeugs.

      Nach unendlichen rumprobieren habe ich festgestellt, wenn man alles was nicht zum script gehört weglässt und <?php in der ersten Zeile steht, ohne sonstige Zeichen oder Leerzeichen dazwischen, dann zeigt der Brausär die Grafik an.

      Bingo. Das ist es, was ich eben meinte.

      Wie war das mit dem blinden Huhn? Da hab ich also ein Korn gefunden und wusste nix mit anzufangen :o)

      Vielen Dank für die ausführliche und verständliche Antwort, jetzt hab ich wieder was gelernt.

      Auch noch einen Schönen Sonntag wünscht,
      Harald (aka TeraVolt)