Wasserzeichen und header
Newbie
- php
Ausgabe von Bildern mit Wasserzeichen ist eigentlich kein Problem.
Wenn ich das Ganze nur temporär lagern will allerdings schon.
Um das Problem mit dem Header zu umgehen erzeuge ich im Hauptscript
das Bild mit Wasserzeichen:
$file = $derbg;
$size = getimagesize($file);
$width = $size[0]; $height = $size[1];
$old_picture = imagecreatefromjpeg($file);
$new_picture = imagecreatetruecolor($width, $height);
imagecopyresampled($new_picture, $old_picture, 0, 0, 0, 0, $width, $height, $width, $height);
$transition = 40; $watermarkfile = imagecreatefrompng('images/wasserzeichen.png');
$waternarkpic_width = imagesx($watermarkfile);
$waternarkpic_height = imagesy($watermarkfile);
$watermarkdest_x = $width / 2 - ($waternarkpic_width / 2); $watermarkdest_y = 260;
imagecopymerge($new_picture, $watermarkfile, $watermarkdest_x, $watermarkdest_y, 0, 0, $waternarkpic_width, $waternarkpic_height, $transition);
$bildname="images/".$anfrage['nr'].".jpg";
imagejpeg($new_picture,$bildname,100);
und rufe dann das externe Script mit dem Header auf:
<img src='imgcr.php'>
So sieht das externe Script (imgcr.php) aus:
<?php
header("Content-type: image/jpeg");
imagejpeg($bildname);
ImageDestroy($bildname);
?>
Das Problem ist: Es wird einfach kein Bild angezeigt und es kommt auch keine Fehlermeldung ala "header already been sent".
Ich habe mir mal mittels echo in der externen Datei die Variable $bildname,die auf das Bild verweisen soll,ausgeben lassen-alles korrekt.
Also wird das Bild korrekt erzeugt,es wird vom Hauptscript korrekt auf das Bild verwiesen.
Wo steckt da der Fehler?
echo $begrüßung;
Um das Problem mit dem Header zu umgehen erzeuge ich im Hauptscript das Bild mit Wasserzeichen:
Warum machst du es in einem ganz anderen Request als das Bild dann letztlich vom Client angefragt wird?
$file = $derbg;
Der Sinn der Umkopierung erschließt sich mit nicht. Weder $derbg noch $file ändert seinen Inhalt im weiteren Verlauf (so du ihn hier offengelegt hast). Statt auf $file kann genauso gut auch auf $derbg zugegriffen werden.
$size = getimagesize($file);
Hast du abgesichert, dass $file auf eine von getimagesize verarbeitbare Datei verweist?
$width = $size[0]; $height = $size[1];
wenn dies nicht der Fall ist, gibt getimagesize() kein Array zurück. Ein false hat keine Array-Elemente auf die zugegriffen werden kann. Hier fehlt eine Fallunterscheidung.
$bildname="images/".$anfrage['nr'].".jpg";
imagejpeg($new_picture,$bildname,100);
Du hast nun eine Grafikdatei irgendwo im Dateisystem abgelegt. Das Script ist danach zu Ende (nehm ich mal an), alle Variableninhalte gehen damit verloren.
So sieht das externe Script (imgcr.php) aus:
<?php
header("Content-type: image/jpeg");
imagejpeg($bildname);
ImageDestroy($bildname);
?>
Was ist der Inhalt der beteiligten Variablen? Wo kommt $bildname her und ist das eine Ressourcenkennung, die mit einer der imagecreate*-Funktionen erzeugt wurde?
Das Problem ist: Es wird einfach kein Bild angezeigt und es kommt auch keine Fehlermeldung ala "header already been sent".
Hast du das error_reporting auf E_ALL stehen (und display_errors auf on)?
Wenn du in imgcr.php eine Fehlermeldung bekommst, dann siehst du die im Browser nur, wenn du dir den Quelltext des Bildes (nicht den der "Hauptdatei") anzeigen lässt. Zum Testen kannst du auch den Header weglassen, dann siehst du bei einem direkten Aufruf von imgcr.php auch Fehlermeldungen (neben den Bilddaten).
Ich habe mir mal mittels echo in der externen Datei die Variable $bildname,die auf das Bild verweisen soll,ausgeben lassen-alles korrekt.
var_dump() ist genauer bei seinen Ausgaben.
Also wird das Bild korrekt erzeugt,es wird vom Hauptscript korrekt auf das Bild verwiesen.
Nochmal gefragt: Was willst du im "Hauptscript" mit dem Bild, wenn du es doch erst in imgcr.php benötigst?
echo "$verabschiedung $name";
Hallo, (echo "hatte_ich_vergessen";)
die Bildausgabe mit Wasserzeichen im Hauptscript funktionierte einwandfrei.Erst durch die Auslagerung in die externe Scriptdatei (imgcr.php) wurde das Bild nicht mehr angezeigt.
Mein Ansinnen war folgendes:
Das Bild sollte nur angezeigt, aber nicht auf dem Server gespeichert werden,da sich dadurch das Datenvolumen vervielfachen würde.
Da mein Hauptscript aber sowohl vor- als auch nach der Bildausgabe viele php und html-Funktionen ausgibt dachte ich,auch um das Problem mit dem header zu umgehen,die Bildausgabe eben über das externe Script zu steuern und das Bild ebenfalls über das externe Script wieder zu löschen.
Sicherlich fehlt mir hier und da das Grundverständnis für derartige Funktionen,aber auch durch nachlesen bin ich da irgendwie nicht schlauer geworden.
Am Anfang habe ich im Hauptscript nach der erfolgreichen Ausgabe des Bildes mit Wasserzeichen versucht das Bild zu löschen- mit dem Ergebnis,dass es dann gar nicht mehr angezeigt wurde.Deshalb (nochmals) die Idee mit dem externen Script und der Header-Lösung.
Von dem doppelten Variablen-Murks mit $file und $derbg mal abgesehen,funktioniert(e) die Ausgabe korrekt,es wurde also auf die korrekte Datei verwiesen.
Der Bildname wird aus der Datenbank gelesen und in die Variable übergeben-es wird auch auf den richtigen Namen verwiesen.
Das einzige Problem,dass ich nicht lösen konnte,war und ist die temporäre Anzeige des Bildes.
echo "Gruß, Newbie";
die;
echo $begrüßung;
die Bildausgabe mit Wasserzeichen im Hauptscript funktionierte einwandfrei.
Wenn "Hauptscript" ein HTML-Dokument ausgeliefert hat, dann kann sich darin kein Bild befunden haben. (Inline-Grafiken in HTML lassen wir mal wegen unpraktikabel außer acht.) Wenn du bei dessen Ausführen eine Datei angelegt hast, und diese in einem zweiten Request abgefragt hast, war das ein Konzeptfehler.
Erst durch die Auslagerung in die externe Scriptdatei (imgcr.php) wurde das Bild nicht mehr angezeigt.
Ebenfalls ist es einer, wenn Erzeugung und Auslieferung mit anschließender Beseitigung getrennte Schritte sind, solange nicht ein eindeutiger Bezug zwischen beiden Schritten hergestellt wurde und außerdem ein Aufräum-Mechanismus für die Beseitigung liegengebliebenen Datenmülls sorgt.
Schau dir doch mal genau an, wie die Bestandteile einer Webseite - also zumindest das was am Ende im Auge des Betrachters ein großes Bild ergibt - angefragt und beantwortet werden. Es gibt als erstes einen Request nach der "Hauptseite". Dieser wird abgearbeitet und danach vergisst der Webserver alles was damit zusammenhing. Das macht er bei jedem Request und das muss so sein, weil er die Ressourcen für andere Requests benötigt. Der Client analysiert den Inhalt und findet darin Verweise auf andere Dokumente, die er unmittelbar zur Darstellung der Seite benötigt. Beispielsweise sind das CSS-Dateien, Javascript-Dateien, Bild-Dateien, Flash- und anderes Zeug. Er kann bereits noch während er die Seite empfängt selbige analysieren und Requests nach den anderen Dateien anstoßen. Er kann aber auch warten bis die Seite vollständig ist und erst dann mit den einzubindenden Dingen weitermachen. Und er kann entscheiden, gar nichts nachzuladen. Zum einen, weil es es vielleicht schon im Cache hat, zum anderen, weil es ihm per Konfiguration verboten ist (z.B. Bilder nachzuladen). Außerdem können beliebig viele Client quasi zur gleichen Zeit deine "Hauptseite" anfordern und anschließend das Bild nachladen wollen. Requests nach Hauptseite und Bild kommen dann in ungeordneter Folge aus unterschiedlichen Richtungen.
Du must also aus Serversicht Requests grundsätzlich als völlig unabhängig voneinander betrachten. Es gibt weder eine Reihenfolge der Requests noch eine Garantie, dass sie überhaupt stattfinden. Erzeugung und Beseitigung von vorübergehenden Daten sollten deshalb immer in dem selben Request stattfinden. Und selbst da musst du noch aufpassen, dass mehrere gleichzeitig diese Datei abfragen können. Temporäre Dateinamen müssen sich voneinander unterscheiden, wenn sich nicht zwei Requests um die selbe Datei prügeln sollen. Oder es muss sichergestellt werden, dass der eine solange wartet bis der andere die Datei wieder freigegeben hat. Für temporäre Dateien siehe tempnam() und tmpfile(), für die Problematik des gleichzeitigen Zugriffs siehe Sperren von Dateien. Wenn du Daten über mehrere Requests hin benötigst, musst du es so einrichten, dass sie jeder Request immer wieder mitsendet oder sie geeignet auf dem Server festhalten (Stichwort: Session).
Wenn du nun das Prinzip verstanden hast, überprüfe bitte nochmal dein Konzept, ob es mit all den genannten Umständen zurecht kommt. Überlege dir auch, welche Daten du für welchen Request benötigst, wo sie her kommen und wie du sicherstellen kannst, dass sie eindeutig und ohne Zwischenfälle dahin kommen.
Mein Ansinnen war folgendes:
Das Bild sollte nur angezeigt, aber nicht auf dem Server gespeichert werden,da sich dadurch das Datenvolumen vervielfachen würde.
Dann leg Erzeugung und Beseitigung in einen einzigen Request. Sorge für einen Ausschluss von Beeinträchtigungen durch parallel laufende Requests.
echo "$verabschiedung $name";
Hallo,
es tut mir leid,aber ich verstehe leider nur Bahnhof.
Als Anfänger wäre mir mit einer einfachen Erklärung oder einem korrigiertem Beispiel anhand meines codes besser geholfen.
Trotzdem danke für deine Bemühungen!
Hi,
es tut mir leid,aber ich verstehe leider nur Bahnhof.
Na das ist doch immerhin schon mal etwas.
Als Anfänger wäre mir mit einer einfachen Erklärung oder einem korrigiertem Beispiel anhand meines codes besser geholfen.
Dass du das bilderzeugende Script als eigenstaendige Ressource aufrufen sollst, also a) ueber <img src="..." ...> eingebunden, und b) nichts ausser Content-Type-Header und Bilddaten ausgebend, faellt hoffentlich mit unter "Bahnhhof" - schliesslich hatten wir das Thema schon oft genug, und wenn man sich ein paar Gedanken ueber die Hintergruende macht, ist es auch nur logisch.
Wenn du das Bild nicht laengerfristig auf Platte speichern willst - dann gebe halt keinen Dateinamen an beim Aufruf der ausgebenden Funktion.
Und wenn das bilderzeugende Script Daten aus dem "Hauptdokument" braucht, um das Bild zu erzeugen, dann uebergebe diese bspw. bei der Einbindung (GET-Parameter), oder ueber eine Session.
MfG ChrisB