Volker: Die Funktion header() innerhalb eines Dokuments

Hallo zusammen.
ich wende mich mit einem recht komplexen Problem an euch, da ich nicht mehr weiterkomme.

Situation:
Ich habe eine Galerie, in der ein jeweiliges einzelnes Bild groß dargestellt wird. Dieses wird mittels eines Parameters an eine Funktion wasserzeichen($param) übergeben, die ein Wasserzeichen auf dieses Bild kopiert und dann unabhängig vom Ursprungsformat (hier angenommen, es ist eine jpeg-Datei) eine png-Datei ausgibt.

  
<?php  
function wasserzeichen ($bild) {  
 // Bild laden  
 $bild = imagecreatefromjpeg($bild);  
 $wasserzeichen = imagecreatefrompng('adresse/wasserzeichen.png');  
 // Header setzten  
 header("Content-type: image/png");  
 // Bild Infos  
 $width = imagesx($bild);  
 $height = imagesy($bild);  
 // Bilder erzeugen  
 $img = imagecreatetruecolor($width, $height);  
 // Bild einfügen  
 imagecopy($img, $bild, 0, 0, 0, 0, $width, $height);  
 // Wasserzeichen einfügen  
 imagealphablending($img, TRUE);  
 imagecolortransparent($wasserzeichen, imagecolorat($wasserzeichen, 0, 0));  
 imagecopymerge ($img, $wasserzeichen, $width-295, $height-28, 0, 0, 285, 18, 50);  
 // Bild anzeigen  
 imagepng($img);  
 return $img;  
 // Speicher freigeben  
 imagedestroy($img);  
}  
?>  

Nun ist es ja so, dass ich die Funktion nicht einfach in einer PHP-Datei an der benötigten Stelle mit
echo "<img src="".wasserzeichen($bildadresse)."" alt="Bild" />"
aufrufen kann, da header() seine Arbeit nicht verrichten kann, wenn vorher schon HTML-code per
echo "..."
ausgegeben wurde.

Meine Idee: Ha, kein Problem, ich modifiziere die Funktion wasserzeichen() so, dass ich vor der Ausgabe von HTML-code eine png-Datei erzeuge, und diese kann ich dann an benötigter Stelle wie gewünscht bearbeiten und als Bild mit Wasserzeichen ausgeben...

Rufe ich jetzt aber Anfang des PHP-Dokuments
$wasserzeichenbild = wasserzeichen("0");
mit der modifizierten version von wasserzeichen() auf:

  
<?php  
function wasserzeichen ($bild) {  
 if ($bild == "0") {  
  // Header setzten  
  header("Content-type: image/png");  
  // Bilder erzeugen  
  $img = imagecreatetruecolor(10, 10);  
  // Bild anzeigen  
  imagepng($img);  
  return $img;  
  // Speicher freigeben  
  imagedestroy($img);  
 } else { ... }  
}  

... dann erscheint bei mir die png-Grafik im Browser und nicht der darauf folgende Quelltext, _obwohl_ ich doch eigentlich einer Variable, die ein Bild beinhaltet, den header zugewiesen habe!?
Anscheinend gilt die header()-Angabe jedoch dann für das gesamte PHP-Dokument.

Wie löse ich also das resultierende Problem:
Ich will eine png-Grafik dynamisch erstellen, in dem ich mitten in einem PHP-Dokument die Funktion wasserzeichen(..) aufrufe, die aus zwei Einzelbildern ein Neues erstellt und mit return ausgibt.

Möglicherweise ist die Lösung trivial, aber ich stecke mit dem Kopf so tief drin, dass ich scheitere :-.
Ich hoffe, ich habe alle Details ausreichend erläutern können.
Danke im Voraus für Hilfe.

Gruß, Volker

  1. Hallo Volker,

    Nun ist es ja so, dass ich die Funktion nicht einfach in einer PHP-Datei an der benötigten Stelle mit
    echo "<img src="".wasserzeichen($bildadresse)."" alt="Bild" />"
    aufrufen kann

    Nein, kannst du nicht. Aber aus einem anderen Grund: Überleg mal, was du machst, wenn du normal ein Bild einbindest.
    a) <img src="URL des Bildes" alt="Alternativtext" />
    b) <img src="Inhalt der Bilddatei" alt="Alternativtext" />

    Alternative: Inline-Grafiken

    Viele Grüße aus Freiburg,
    Marian

    --
    Microsoft broke Volkswagen's world record: Volkswagen made only 22 million bugs!
    <!--[if IE]><meta http-equiv="refresh" content="0; URL=http://www.getfirefox.com"><[endif]-->
    1. Alternative: Inline-Grafiken

      Ich muss gestehen, davon hab ich noch nie gehört... man lernt nie aus ;-). Danke.
      Wenn ich ein Bild also mit
      <img src="data:image/png;base64,DATEN">
      aufrufe, was muss ich dann in meiner Funktion wasserzeichen(..) ändern?
      Kann ich das header(..) löschen? Wenn ich das nicht tun würde, hätte ich ja immer noch das Problem, das mir PHP nen fehler um die Ohren haut.

      Gruß, Volker

      1. Hallo Volker,

        Alternative: Inline-Grafiken

        Ich muss gestehen, davon hab ich noch nie gehört... man lernt nie aus ;-). Danke.
        Wenn ich ein Bild also mit
        <img src="data:image/png;base64,DATEN">
        aufrufe, was muss ich dann in meiner Funktion wasserzeichen(..) ändern?
        Kann ich das header(..) löschen? Wenn ich das nicht tun würde, hätte ich ja immer noch das Problem, das mir PHP nen fehler um die Ohren haut.

        Das ist was komplett anderes und wahrscheinlich auch nicht dass, was du willst. Mit src gibst du die _Quelle_ des Bildes an, nicht den kompletten Inhalt aus. Der Browser holt sich das Bild dann in einer eigenen Anfrage.
        Du musst einfach sowas wie src="wasserzeichen.php?image=bild.png" schreiben, und in wasserzeichen.php fügst du dann die genannte Funktion ein.

        Das mit den Inline-Grafiken ist nur eine Methode, Grafiken (und anderes) direkt im HTML-Code zu referenzieren. Das habe ich nur genannt, weil du das gemacht hast, aber nicht auf die richtige Art. Ich glaube aber nicht, dass du das wolltest.

        Viele Grüße aus Freiburg,
        Marian

        --
        Microsoft broke Volkswagen's world record: Volkswagen made only 22 million bugs!
        <!--[if IE]><meta http-equiv="refresh" content="0; URL=http://www.getfirefox.com"><[endif]-->
  2. Tach.

    ... die ein Wasserzeichen auf dieses Bild kopiert und dann unabhängig vom Ursprungsformat (hier angenommen, es ist eine jpeg-Datei) eine png-Datei ausgibt.

    Oha, das kann u. U. ganz schon auf die Dateigröße gehen ...

    function wasserzeichen ($bild) {
    ...
    // Bild anzeigen
    imagepng($img);
    return $img;
    // Speicher freigeben
    imagedestroy($img);
    }

      
    Die letzte Zeile deiner Funktion wird nicht ausgeführt, da du in der Zeile davor wasserzeichen() mit return bereits verläßt. Das nur am Rande.  
      
      
    
    > Meine Idee: Ha, kein Problem, ich modifiziere die Funktion wasserzeichen() so, dass ich vor der Ausgabe von HTML-code eine png-Datei erzeuge, und diese kann ich dann an benötigter Stelle wie gewünscht bearbeiten und als Bild mit Wasserzeichen ausgeben...  
      
    Nein, du verwechselst da etwas. Mit einer Angabe wie  
      
        <img src="blablupp.png" alt="Bild" />  
      
    veranlaßt du den Browser, vom Server die Datei blablupp.png anzufordern. Das passiert also \*nach\* dem Ausliefern der HTML-Datei.  
      
    Wenn du deine Waaserzeichen-Funktion in ein separates Skript wasserzeichen.php steckst, kannst du dieses z. B. mit  
      
        <img src="wasserzeichen.php?img=blablupp.png" alt="Bild" />  
      
    aufrufen. Deine Funktion liefert die Datei nach den Modifikationen dann mit dem entsprechenden Header aus und alles ist in Butter. Daß du die Originalbilder vernünftig wegschließt versteht sich von selbst.  
      
      
    Um das Bild mit Wasserzeichen nicht bei jedem Ausliefern der Bilddatei neu generieren zu müssen, bietet sich ein Caching-Mechanismus an. Der überprüft, ob die modifizierte Datei bereits existiert. Ist dies nicht der Fall, erzeugt und speichert er sie. Beim nächsten Aufruf muß dann nur noch die bereits modifizierte Bilddatei ausgeliefert werden.  
    
    -- 
    Once is a mistake, twice is jazz.
    
    1. Um das Bild mit Wasserzeichen nicht bei jedem Ausliefern der Bilddatei neu generieren zu müssen, bietet sich ein Caching-Mechanismus an. Der überprüft, ob die modifizierte Datei bereits existiert. Ist dies nicht der Fall, erzeugt und speichert er sie.

      Natürlich sollte die neu erstellte Datei anschließend auch an den Browser geschickt werden ... %-)

      --
      Once is a mistake, twice is jazz.
    2. Wenn du deine Waaserzeichen-Funktion in ein separates Skript wasserzeichen.php steckst, kannst du dieses z. B. mit

      <img src="wasserzeichen.php?img=blablupp.png" alt="Bild" />

      aufrufen. Deine Funktion liefert die Datei nach den Modifikationen dann mit dem entsprechenden Header aus und alles ist in Butter.

      Das heißt der Fehler wird durch den Unterschied
      (ich:) <img src=".wasserzeichen.php." alt="Bild" />
      (du:)  <img src="wasserzeichen.php?img=blablupp.png" alt="Bild" />
      behoben?
      Holla, du könntest sogar gar nicht mal so Unrecht haben... :-)
      Thx.

      Gruß, Volker

  3. Moin!

    Nun ist es ja so, dass ich die Funktion nicht einfach in einer PHP-Datei an der benötigten Stelle mit
    echo "<img src="".wasserzeichen($bildadresse)."" alt="Bild" />"
    aufrufen kann, da header() seine Arbeit nicht verrichten kann, wenn vorher schon HTML-code per
    echo "..."
    ausgegeben wurde.

    Nehmen wir das mal auseinander:

    datei.php enthält:

    <?php

    pla

    blub

    ?>
    <!-- irgendwelches HTML -->
    <img src="pfad/bild_mit_wasserzeichen.php" ... >
    <!-- irgendwelches HTML -->
    <?php

    blub

    pla

    ?>

    Die Ausgabe wird an den Browser gesendet und erst der holt dann "http://Deinserver.tld/pfad/bild_mit_wasserzeichen.php" neu ab und bekommt auch neue header. Was sollte daran nicht funktionieren?

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
    1. Die Ausgabe wird an den Browser gesendet und erst der holt dann "http://Deinserver.tld/pfad/bild_mit_wasserzeichen.php" neu ab und bekommt auch neue header. Was sollte daran nicht funktionieren?

      Mein Fehler, den ich übersehen hatte, war der, dass ich anstatt die Grafik zu referenzieren die Grafik mittels
      <img scr="".wasserzeichen()." />
      in den HTML-Code eingebaut habe (man beachte die beiden Punkte!!!).
      Ohne funktioniert's wunderbar.

      Gruß, Volker