André: Bildobjekt in Session übergeben

Hallo zusammen,

ich hänge immer noch an meinem Problem, ein Bild als Stream in einer HTML-Seite auszugeben.
Das Bild wird in einem Script so erzeugt:

$im = @imageCreate (100, 100) or die ("Fehlermeldung");
...
session_start();
$_SESSION['map'] = $im;
session_write_close();

dazu gibt das Script dann in der HTML-Seite eine Zeile aus:

<img src="image.php" width="100" height="100" alt="" border="0">

Im Script "image.php" steht dann folgendes:

header("Content-type:image/png");
session_start();
$im = $_SESSION['map'];
ImagePNG($im);

lasse ich das ganz dann laufen, dann bringt mir image.php folgende Fehlermeldung:

imagepng(): supplied argument is not a valid Image resource

Ich denke, der Fehler liegt daran, dass ich eine Bildressource nicht so einfach in eine Sessionvariable schreiben kann. Ich habe auch schon probiert, Das Bild per $_SESSION['map'] = serialize($im) in die Session zu schreiben und per $im = unserialize($_SESSION['map']) wider aus der Session zu lesen. Bringt aber nix, kommt die selbe Fehlermeldung.

Was mache ich falsch?

Gruß, André

  1. hi,

    ich hänge immer noch an meinem Problem, ein Bild als Stream in einer HTML-Seite auszugeben.

    Darf man fragen, _warum_ du das Bild erst in der Session zwischenspeichern möchtest - anstatt es vom erzeugenden Script auch gleich an den Client ausgeben zu lassen?

    Das Bild wird in einem Script so erzeugt:
    $im = @imageCreate (100, 100) or die ("Fehlermeldung");

    $im ist jetzt eine "Image resource" - es enthält nicht die eigentlichen Bilddaten, sondern es ist lediglich eine Art "Zeiger" auf ein Bildobjekt irgendwo im Speicherbereich deines Scriptes.

    session_start();
    $_SESSION['map'] = $im;
    session_write_close();

    Jetzt hast du lediglich diesen Zeiger in die Session geschrieben.

    Im Script "image.php" steht dann folgendes:

    header("Content-type:image/png");
    session_start();
    $im = $_SESSION['map'];
    ImagePNG($im);

    Jetzt hast du dir den "Zeiger" wiedergeholt. Dieser mag eine bestimmte Speicheradresse oder sonstwas enthalten (ich weiß nicht genau, wie PHP das realisiert hat) - auf jeden Fall zeigt er jetzt auf irgendeinen Murks, und nicht mehr auf dein Bild - denn dieses war ein Objekt des vorherigen Scriptes, und ist deshalb mit dessen Ende natürlich ins Datennirwana geschickt worden.

    lasse ich das ganz dann laufen, dann bringt mir image.php folgende Fehlermeldung:

    imagepng(): supplied argument is not a valid Image resource

    Logisch, wie oben gesagt: Du hast irgendein altes Lesezeichen - aber das Buch ist längst weggeworfen worden. (OK, der hinkt ein wenig :-))

    Ich denke, der Fehler liegt daran, dass ich eine Bildressource nicht so einfach in eine Sessionvariable schreiben kann.

    Kannst du schon - aber sie ist außerhalb des Scriptes, in dem sie erzeugt wurde, wertlos.

    Ich habe auch schon probiert, Das Bild per $_SESSION['map'] = serialize($im) in die Session zu schreiben und per $im = unserialize($_SESSION['map']) wider aus der Session zu lesen. Bringt aber nix, kommt die selbe Fehlermeldung.

    Wie gesagt, $im enthält _nicht_ die Bilddaten.

    Die Bilddaten gibt dir imagepng() zurück.
    Du könntest diese Ausgabe abfangen (Stichwort: output buffering), und dann serialisiert in die Session schreiben.

    Das dürfte aber idR. ziemlich unperformant sein.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. ich hänge immer noch an meinem Problem, ein Bild als Stream in einer HTML-Seite auszugeben.

      Darf man fragen, _warum_ du das Bild erst in der Session zwischenspeichern möchtest - anstatt es vom erzeugenden Script auch gleich an den Client ausgeben zu lassen?

      Hatte ich vor ein paar Tagen hier schon mal beschrieben. Der Tip mit der Session kam von dir :)

      Mein Problem ist folgendes:
      Ich habe eine Datenbank, in der die Informationen stehen, aus denen ein Bild erzeugt wird.
      Die Parameter, die ich angebe, um die richtigen Daten aus der DB auszulesen sind recht umfangreich. Ebenso die Daten aus der DB.

      Das erzeugt Bild selber ist relativ klein (~200x200 pixel).

      Das Script, welches die HTML-Seite aufbaut, in der das Bild gezeigt werden woll, braucht unbedingt Daten, die erst bei der Erzeugung des Bildes entstehen (Anzahl Objekte, Art der Objekte, etc.)
      Also lasse ich dieses Script auch schon sämtliche Datenbankanfragen machen.

      Das Ergebnis der DB-Abfragen kann durchaus über 1 MB groß sein. Das möchte ich also nicht unbedingt per Session übertragen, denn das fertige Bild ist ja wesentlich kleiner. Deshalb möchte ich das fertige Bild in der Session speichern.

      Gruß, André

      1. hi,

        Darf man fragen, _warum_ du das Bild erst in der Session zwischenspeichern möchtest - anstatt es vom erzeugenden Script auch gleich an den Client ausgeben zu lassen?

        Hatte ich vor ein paar Tagen hier schon mal beschrieben. Der Tip mit der Session kam von dir :)

        Ach so ja *grins*

        Das Script, welches die HTML-Seite aufbaut, in der das Bild gezeigt werden woll, braucht unbedingt Daten, die erst bei der Erzeugung des Bildes entstehen (Anzahl Objekte, Art der Objekte, etc.)
        Also lasse ich dieses Script auch schon sämtliche Datenbankanfragen machen.

        Das Ergebnis der DB-Abfragen kann durchaus über 1 MB groß sein. Das möchte ich also nicht unbedingt per Session übertragen, denn das fertige Bild ist ja wesentlich kleiner.

        Per Session "überträgst" du keine "Daten" zwischen Server und Client.
        Die Session-Daten werden _auf dem Server_ in eine Session-Datei geschrieben.
        Lediglich die Session-ID wird vom Client zum Server übertragen.
        Beim nächsten Aufruf eines Scriptes sendet der Client die Session-ID wieder mit - bspw. als GET-Parameter.
        Mit dieser ID weiß der Server jetzt, aus welcher Session-Datei er die dort gespeicherten Daten wieder auslesen kann.

        Deshalb möchte ich das fertige Bild in der Session speichern.

        Wie gesagt, das ginge nur, wenn du die Ausgabe von imagepng() abfängst und in die Session schreibst.

        Anders hast du folgende zwei praktikablen Möglichkeiten:

        Erstens: Du lässt das Hauptscript die ermittelten Daten in die Session schreiben. Das Bild bindest du mit
        <img src="bildscript.php?{Sessionname=Session-ID}" ...>
        ein.
        bildscript.php liest jetzt die Daten wieder aus der Session aus, und erzeugt damit das Bild und sendet es an den Client.

        Zweitens: Du lässt das Hauptscript das Bild bereits erzeugen und auf Platte speichern (bei imagepng zweiten Parameter nutzen). Einen zufälligen Bildnamen kannst du mittels uniq() o.ä. erzeugen.
        Dann bindest du das Bild entweder mit
        <img src="{von uniqid erzeugter name}" ...>
        ein - Nachteil: Bild bleibt auf dem Server gespeichert, Verzeichnis wird allmählich vollgemüllt.
        Oder du verlinkst die src des Bildes wiederum auf ein Script, welchem der temporäre Bildname wiederum als Parameter übergeben wird. Dieses Script gibt nun die Bilddaten an den Client aus (header gefolgt von readfile o.ä.), und löscht anschließend die temporäre Bilddatei wieder.
        Das wäre auch eine Art von Session-Mechanismus, der gleich das Bild enthält - nur eben selber implementiert.

        Bei beiden Methoden wäre nur darauf zu achten, dass der Client das Bild nicht schon anfordert, bevor die Daten in der Session stehen, bzw. das Bild auf Platte abgespeichert wurde.

        Bei der Session-Variante sollte also session_write_close _vor_ der Ausgabe des <img>-Tags erfolgen;
        bei der zweiten Methode sollte es ausreichen, wenn das Speichern auf Platte mittels imagepng() vor der Ausgabe des <img>-Tags erfolgt.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }