Nadal: Bild erzeugen mit GD => Einbetten in HTML

Hallo,

ich würde gerne eine Bild mit dem Modul GD generieren und dass dann ohne zwischen zu speichern direkt ausgeben.

Meine Ansatz:

use GD;  
my $bild = new GD::Image(200,25);  
my $schwarz = $bild->colorAllocate(0,0,0);  
my $weiss = $bild->colorAllocate(255,255,255);  
$bild->string(gdLargeFont,0,3,"$par_plaintext",$weiss);  
print $bild->png;  
  
print <<show_html;  
  
<html>  
<head>  
<title>Grafik</title>  
</head>  
<body>  
  
<h1>Ttest</h1>  
  
<p><img src="$bild->png"></p>  
  
</body>  
</html>  
  
show_html  

Geht leider nicht, da die Variable: $bild->png anstatt ein Bild den Binärcode ausgibt (kann es leider nicht posten, da das Formular es nicht zulässt).

Wie muss ich das korrekt machen?

Danke.

Nadal

P.S.:  Nur das Bild ausgeben ist kein Problem.
Sowas funktioniert also ...

#!/usr/bin/perl -w  
  
use GD;  
use strict;  
  
my $bild = new GD::Image(200,25);  
my $schwarz = $bild->colorAllocate(0,0,0);  
my $weiss = $bild->colorAllocate(255,255,255);  
$bild->string(gdLargeFont,0,3,"123213",$weiss);  
  
  
print "Content-type: image/gif\n\n";  
print $bild->gif;
  1. hi,

    ... $bild->png anstatt ein Bild den Binärcode ausgibt

    Bytes sind das.

    (kann es leider nicht posten, da das Formular es nicht zulässt).

    Der Text, den Du hier postest, das sind auch nur Bytes.

    Wie muss ich das korrekt machen?

    Wenn ein Browser text/html und image/png, also ein Image mit Text zusammen darstellen will, braucht er zwei Requests, die beantwortet werden möchten.

    Bis die Browser einen echten Multipart-Content, Bilder, Texte... in einer Response bekommen und verarbeiten können, tja, da müssen wir vielleicht noch ein bischen warten.

    Hotti

    1. Ok ...

      Und ein Bild nach dem erzeugen und NACH dem ersten "ausliefern" zu löschen geht leider auch nicht.

      <html>  
      <head>  
      <title>Grafik</title>  
      </head>  
      <body>  
        
      <h1>Test</h1>  
        
      <p><img src="mypic.png"></p>  
        
      </body>  
        
        
      unlink ("mypic.png");
      

      Also geht schon, aber leider findet er das Bild nicht, da es schon gelöscht ist, bevor der Browser es dargestellt hat. Gibt es da eine Möglichkeit? Also ein sleep von dem unlink hat leider nicht geholfen.

      1. Hallo,

        Siehe Antwort von Joachim. Der Browser erwartet also im img-Tag und src-Attribut einen URL, wo er die Daten holt.

        Es gibt jedoch noch eine andere Möglichkeit, heißt inline-Grafik und ist auch in SELFHTML beschrieben.

        Im Attr src

        <p><img src="mypic.png"></p>

        ^ /img/img.gif (URL)

        steht bei einer inlineGrafik
        src = data:image/gif;binary,DATA

        oder
        src= data:image/gif;base64,DATA

        (nach rfc239) wobei DATA die Binary ist, im 2. Fall als Base64.

        Auf diese Art kann der Browser alles in _einer Response bekommen. Es ist jedoch damit zu rechnen, dass das nicht alle Browser unterstützen.

        Hotti

        1. hi again,

          Beispiel Perl-CGI

          Hotti

          PS: Das Script ist recht einfach anzupassen. Getestet mit FF und IE(neuerer Bauart)

          #~~~~~~~~~~~~~~~~~~~~ Script ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            
          #!/usr/bin/perl  
            
          use strict;  
          use warnings;  
          use myConfig qw($cfg);  
          use IO::File;  
          use MIME::Base64 qw(encode_base64);  
            
          print "Content-Type:text/html; charset=UTF-8\n\n";  
          print "<h1>Image Inline</h2>";  
            
            
          if(-f "$cfg->{path}->{filedir}/red.gif"){  
          	my $fh = new IO::File "$cfg->{path}->{filedir}/red.gif", O_RDONLY|O_BINARY;  
          	my $binary = undef;  
          	read($fh, $binary, -s _); # Lese BinärDatei  
          	  
          	# jetzt kann der Inhalt ausgegeben werden  
          	# zunächst die Inline-Grafik  
          	my $inline = "data:image/gif;base64,".encode_base64($binary);  
          	print qq(  
          		<p>  
          			Unten sollte eine Grafik zu sehen sein:  
          		</p>  
          		  
          		<p>  
          			<img src="$inline">  
          		</p>  
          	  
          	);  
            
          }  
          else{  
          	print "<p>Image nicht gefunden</p>";  
          }  
          
          
        2. Ok, aber meine letzte Frage bezog sich eher darauf, wie ich eine Datei erzeugen kann

          open(pic,">pics/tmp.png");  
          print pic $bild_var;  
          close(pic); 
          

          Dann ausgeben:

          <img src="pics/tmp.png" alt="Tmp pic">

          und dann löschen:

            
          unlink ("pics/tmp.png");
          

          Wenn ich das in der Reihenfolge in einem Script mache, dann findet er das Bild nicht, obwohl ich erst nach der Ausgabe das Bild lösche.

          Geht das auch nicht irgendwie?

          1. Hi,

            Ok, aber meine letzte Frage bezog sich eher darauf, wie ich eine Datei erzeugen kann

            open(pic,">pics/tmp.png");

            print pic $bild_var;
            close(pic);

            
            >   
            > Dann ausgeben:  
            >   
            > `<img src="pics/tmp.png" alt="Tmp pic">`{:.language-html}  
            >   
            > und dann löschen:  
            >   
            > ~~~perl
              
            
            > unlink ("pics/tmp.png");
            
            

            Wenn ich das in der Reihenfolge in einem Script mache, dann findet er das Bild nicht, obwohl ich erst nach der Ausgabe das Bild lösche.

            Mach dir doch bitte erst mal grundlegende Zusammenhänge bei der Client-Server-Kommunikation über HTTP und im Zusammenhang mit HTML klar ...

            Du erstellst deine Bild-Datei,
            du erzeugst dein HTML mit dem IMG-Element,
            du löschst die Datei wieder

            • alles in einem Scriptablauf.

            Erst *Äonen* *später* kommt jetzt irgendein Client („Browser“), und sagt zum Server, „gib mir mal bitte das Bild, das unter folgender Adresse erreichbar ist: ...“
            Was sagt der Server dazu? Natürlich „hab ich nicht, die Datei hat doch schon vor Ewigkeiten jemand, dem elementares Grundlagenwissen fehlt, wieder löschen lassen!“

            Geht das auch nicht irgendwie?

            Wenn du das Bild erst löschst, *nachdem* der Client es angefordert hat - natürlich.
            Aber wenn es nur ein einziges mal angefordert werden soll - was soll es dann dann überhaupt erst als Datei auf der Platte?

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. Geht das auch nicht irgendwie?

              Wenn du das Bild erst löschst, *nachdem* der Client es angefordert hat - natürlich.

              Mach ich ja. Das der Quelltext oben ist ein Script mit den 3 steps..

              1. Bild erzeugen
              2. Ausgabe Client ( print html )
              3. Bild löschen

              Geht das in einem script ode nicht?

              Aber wenn es nur ein einziges mal angefordert werden soll - was soll es dann dann überhaupt erst als Datei auf der Platte?

              Wollte ich erst ja auch nicht, sondern als Krücke da ich eine inline-Grafik, wie von Hotti nun beschrieben nicht hinbekommen hatte. Den Ansatz von Joachim möchte ich nicht, da dort dann paramter, welche ich nicht im HTML-Quelltext haben will übergeben werden müssen.
              Sprich
              <p><img src="/php/image.pl?geheim=geheimnis"></p>

              1. Hi,

                Wenn du das Bild erst löschst, *nachdem* der Client es angefordert hat - natürlich.

                Mach ich ja.

                Nein, machst du ziemlich sicher nicht.

                Das der Quelltext oben ist ein Script mit den 3 steps..

                1. Bild erzeugen
                2. Ausgabe Client ( print html )
                3. Bild löschen

                Geht das in einem script ode nicht?

                Nicht, wenn du das Bild schon wieder löschst, bevor der Client überhaupt die Chance hatte, es anzufordern.

                Den Ansatz von Joachim möchte ich nicht,

                Ist aber der sinnvollste.

                da dort dann paramter, welche ich nicht im HTML-Quelltext haben will übergeben werden müssen.

                Dann nutze Sessions o.ä.

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
              2. hi,

                Mach ich ja. Das der Quelltext oben ist ein Script mit den 3 steps..

                1. Bild erzeugen
                2. Ausgabe Client ( print html )
                3. Bild löschen

                Geht das in einem script ode nicht?

                Nicht in Deiner Reihenfolge. Beachte die Antwort vom Chris, er hats gut erklärt.

                Untenstehend noch eine andere Variante, es dennoch mit einem Script zu machen. Wir müssen davon ausgehen, dass es zwei Requests sind. Daher kriegt die IMG-Ressource, die vom gleichen Script erstellt werden soll, einen Parameter. Beachte, dass eine Fehlerbehandlung nur übers Error_Log des Webservers möglich ist, z.B. wenn ein die($!) auftritt (no such file...).

                Hotti

                #~~~~~~~~~~~~~~~~~~~~~~ script ~~~~~~~~~~~~~~~~~~~~~+

                  
                #!/usr/bin/perl  
                  
                use strict;  
                use warnings;  
                use myConfig qw($cfg);  
                use IO::File;  
                use CGI;  
                  
                my $u = CGI->new;  
                  
                # dieser Teil erzeugt die Grafik  
                # es ist ein Request mit Parameter  
                # Fehlerbehandlung nur per error_log des Webservers!!!!  
                if($u->param('img')){  
                	binmode STDOUT;  
                	print $u->header('image/gif');  
                	# IMG-Datei wird eingelesen, wenn vorhanden  
                	if(-f "$cfg->{path}->{filedir}/red.gif"){  
                		my $fh = new IO::File "$cfg->{path}->{filedir}/red.gif", O_RDONLY|O_BINARY;  
                		die $! if not defined $fh; # error_log gucken!!!  
                		read $fh, my $bin, -s _;  
                		print $bin;  
                		$fh->close;  
                	}  
                	else{ die $! } # siehe error_log!  
                }  
                # dieser Teil erzeugt die Ausgabe von HTML  
                # das ist ein Request ohne Parameter  
                else{  
                	print $u->header('text/html; charset=UTF-8'), qq(  
                		<h2>Grafik mit Text</h2>  
                		  
                		<p>Untenstehend die gewünschte Grafik:</p>  
                		  
                		<p>  
                			<img src="$ENV{SCRIPT_NAME}?img=1" alt="Ein Bild!" width='127' height='38' title="BildDings">  
                		</p>  
                	);  
                  
                }  
                
                
  2. Hi,

    <p><img src="$bild->png"></p>

    nein.
    <p><img src="/php/image.php"></p>

    Du schreibst also ein Script, das ein Bild per GD erzeugt. In dem Script notierst Du einen entsprechenden header:
    header("Content-Type: image/jpeg");

    Dieses Script bindest Du dann als Bild-Src ein.

    Gruesse, Joachim

    --
    Am Ende wird alles gut.