j4nk3y: imagettftext() erkennt Font nicht

Hallo zusammen,

ich arbeite gerade an einem Kreisdiagramm welches durch php mittels Datanbankzugriff erstellt wird. Soweit klappt das auch ganz gut, jedoch gibt es ein seltsames Problem was ich nicht verstehe.

$frage_b = "SELECT a,b,c,d,e FROM tabelle WHERE id = $p";
$fragen_b = mysql_query($frage_b);
$bev = mysql_fetch_array($fragen_b);
if($bev['e'] < 1000)
{
	unset($bev['e']);
}
$q = 0;
while($q < 9)
{
	unset($bev[$q]);
	$q++;
}

$breite = 400;
$hoehe = 210;
$radius = 200;
$start_x = ($breite/3)*2;
$start_y = $hoehe/2;

$rand_oben = 20;
$rand_links = 20;
$punktbreite = 10;
$abstand = 10;
$schriftgroesse = 10;

$diagramm = imagecreatetruecolor($breite, $hoehe); 

$schwarz = imagecolorallocate($diagramm, 0, 0, 0);
$weiss = imagecolorallocate($diagramm, 255, 255, 255);

$color1 =  imagecolorallocate($diagramm, 0, 191, 255);
$color2 = imagecolorallocate($diagramm, 24, 116, 205);
$color3 = imagecolorallocate($diagramm, 0, 0, 205);
$color4 = imagecolorallocate($diagramm, 0, 205, 102);
$color5 = imagecolorallocate($diagramm, 238, 201, 0);
$color6 = imagecolorallocate($diagramm, 255, 133, 0);
$color7 = imagecolorallocate($diagramm, 255, 48, 48);
$color8 = imagecolorallocate($diagramm, 139, 26, 26);
$color9 = imagecolorallocate($diagramm, 94, 94, 94);

imagefill($diagramm, 0, 0, $weiss);

$i = 0;
$winkel = 0;
$gesamt = array_sum($bev);

foreach($bev as $key => $value)
{
	$i++;
	$start = $winkel;
	$winkel = $start + $value*360/$gesamt;
	$color = "color".$i;
	imagefilledarc($diagramm, $start_x, $start_y, $radius, $radius, $start, $winkel, $$color, IMG_ARC_PIE);
	
	$unterkante = $rand_oben + $punktbreite + ($i - 1) * ($punktbreite + $abstand);
	
	imagefilledrectangle($diagramm, $rand_links, $rand_oben + ($i - 1) * ($punktbreite + $abstand), $rand_links+$punktbreite, $unterkante, $$color);
	imagettftext($diagramm, $schriftgroesse, 0, $rand_links+$punktbreite+5, $unterkante-$punktbreite/2 + $schriftgroesse/2, $schwarz, "arial.ttf", $key." ".round($value*100/$gesamt, 2)." %");
	imagejpeg($diagramm, "test.jpg");
	
}

Das problem besteht nun darin, dass wenn ich diese Diagramm.php direkt über xampp ausführe alles wunderbar ohne Fehler angezeigt wird. Jedoch binde ich diese Datei um 2 Ecken in eine Seite ein funktioniert es nicht mehr.

Das stellt sich wie folgt dar: Ich lade die Seite und in einer <section> wird eine .php aufgerufen, in dieser läuft eine foreach schleife ein Array durch und gibt per echo einen html Quelltext an die Seite zurück. In diesem Quelltext greife ich dann auf die Diagramm.php per include zu. Und in diesem Fall wird die arial.ttf welche im selben Verzeichnis wie die Diagramm.php liegt nicht erkannt und es wird der Fehler:

Warning: imagettftext(): Invalid font filename in...

ausgegeben.

php manual und eine längere Suche ergaben bisher leider keine brauchbare Lösung.

Hoffe jemand kann mir da weiter helfen.

Gruß

Jo

  1. Hallo,

    Und in diesem Fall wird die arial.ttf welche im selben Verzeichnis wie die Diagramm.php liegt nicht erkannt und es wird der Fehler:

    Warning: imagettftext(): Invalid font filename in...

    ausgegeben.

    php manual und eine längere Suche ergaben bisher leider keine brauchbare Lösung.

    Laut dem verlinkten Manual wird der Dateiname ohne Extension übergeben. Außerdem gibt es Unterschiede je nach verwendeter Library, hast du geprüft, ob es unterschiedliche Versionen sind? Hast du mal Großschreibung "Arial" probiert? Wenn du "um zwei Ecken einbindest", stimmt dann noch der Pfad?

    Gruß
    Kalk

  2. Hallo,

    [...]
    	imagejpeg($diagramm, "test.jpg");
    

    also halten wir mal fest: Dieses Script gibt eine JPEG-Bildressource aus. Wobei ich ehrlich gesagt noch den Header "Content-Type: image/jpeg" vermisse; ich weiß aber nicht, ob imagejpeg() das nicht möglicherweise von sich aus erledigt.

    Das problem besteht nun darin, dass wenn ich diese Diagramm.php direkt über xampp ausführe alles wunderbar ohne Fehler angezeigt wird. Jedoch binde ich diese Datei um 2 Ecken in eine Seite ein funktioniert es nicht mehr.

    Halt halt! Du wirst schon wieder viel zu schwammig!
    Wie machst du das genau? Exakten Code, bitte.

    Ich lade die Seite und in einer <section> wird eine .php aufgerufen, in dieser läuft eine foreach schleife ein Array durch und gibt per echo einen html Quelltext an die Seite zurück.

    Das ist entweder total konfus beschrieben oder falsch. Du kannst nicht einfach so aus HTML heraus "eine .php aufrufen". Du kannst höchstens eine externe Ressource einbinden, etwa das oben beschriebene Script als Bild. Aber nicht als HTML.

    In diesem Quelltext greife ich dann auf die Diagramm.php per include zu.

    Zeigen, bitte.

    Und in diesem Fall wird die arial.ttf welche im selben Verzeichnis wie die Diagramm.php liegt nicht erkannt und es wird der Fehler:

    Warning: imagettftext(): Invalid font filename in...

    ausgegeben.

    Falsches Verzeichnis??

    Hoffe jemand kann mir da weiter helfen.

    Hoffe ich auch. Aber dazu musst du etwas präziser mit deinen Informationen werden.

    So long,
     Martin

    1. Hey,

      Zeigen, bitte.

      Also in der .php Datei die vom Browser ausgegeben wird steht:

      <section id="haupt">
      <?php include('../functions/php/uebersicht.php')?>
      </section>
      

      in der uebersicht.php wird:

      for($e = 0; $e < $count; $e++)
      {
      	...
      	$class_eintrag = '"eintrag"';
      	$class_zeile = '"eintrag_zeile"';
      	$class_eintrag_links = '"eintrag_links"';
      	$class_eintrag_rechts = '"eintrag_rechts"';
      	
      	
      	
      	echo "
      	<section class=$class_eintrag>
      		<section class=$class_zeile>
      			<article class=$class_eintrag_links>
      			<p>Feld 1 <br /> $ergebnis_s[0]:$ergebnis_s[1]:$ergebnis_s[2]:$ergebnis_p[1] , $col_name</p>
      			</article>
      			<article class=$class_eintrag_rechts>
      			<p>Feld 2</p>
      			</article>
      		</section>
      		<section class=$class_zeile>
      			<article class=$class_eintrag_links>
      				<p>Feld 3</p>
      			</article>
      			<article class=$class_eintrag_rechts>
      				<p>Feld 4</p>
      				<?php include_once('../functions/php/dia.php'); ?>
      			</article>
      		</section>
      	</section>";
      

      ausgegeben.

      wie mir grad aufgefallen ist, kann das nicht funktionieren da die dia.php an der Stelle in der ersten .php Datei nicht aufgerufen/eingebunden wird.

      vorher hatte ich das etwas anders: (2ter Weg)

      include('dia.php')
      
      for($e = 0; $e < $count; $e++)
      {
      	...
      	$class_eintrag = '"eintrag"';
      	$class_zeile = '"eintrag_zeile"';
      	$class_eintrag_links = '"eintrag_links"';
      	$class_eintrag_rechts = '"eintrag_rechts"';
      	
      	
      	
      	echo "
      	<section class=$class_eintrag>
      		<section class=$class_zeile>
      			<article class=$class_eintrag_links>
      			<p>Feld 1 <br />                $ergebnis_s[0]:$ergebnis_s[1]:$ergebnis_s[2]:$ergebnis_p[1] , $col_name</p>
      			</article>
      			<article class=$class_eintrag_rechts>
      			<p>Feld 2</p>
      			</article>
      		</section>
      		<section class=$class_zeile>
      			<article class=$class_eintrag_links>
      				<p>Feld 3</p>
      			</article>
      			<article class=$class_eintrag_rechts>
      				<p>Feld 4</p>
      				echo "<img src='test.jpg' />";
                                      echo '<p>$gesamt</p>;
      			</article>
      		</section>
      	</section>";
      

      Da klappt zwar die Ausgabe des Diagramms aber er erkennt den relativen Pfad zur .ttf nicht und in diesem fall ändert sich auch der Pfad nicht.

      Hab auch gerade herrausgefunden, dass ein absoluter Pfad "F:xampp/htdocs/.../dia.php" funktioniert.

      Kurz: wenn ich die dia.php direkt über ein Browser öffne wird die .ttf im selben Verzeichnis wie die dia.php gefunden. Und wenn die uebersicht.php die dia.php aufruft wird der Pfad nicht erkannt und es gibt eine Fehlermeldung.

      Gruß

      Jo

      1. Hallo,

        Also in der .php Datei die vom Browser ausgegeben wird steht:

        <section id="haupt">
        <?php include('../functions/php/uebersicht.php')?>
        </section>
        

        okay soweit. Vorausgesetzt, PHP darf im Verzeichnispfad nach oben über das aktuelle Verzeichnis hinaus suchen.

        in der uebersicht.php wird:

        	echo "
        	<section class=$class_eintrag>
        		<section class=$class_zeile>
        			<article class=$class_eintrag_links>
        			<p>Feld 1 <br /> $ergebnis_s[0]:$ergebnis_s[1]:$ergebnis_s[2]:$ergebnis_p[1] , $col_name</p>
        			</article>
        			<article class=$class_eintrag_rechts>
        			<p>Feld 2</p>
        			</article>
        		</section>
        		<section class=$class_zeile>
        			<article class=$class_eintrag_links>
        				<p>Feld 3</p>
        			</article>
        			<article class=$class_eintrag_rechts>
        				<p>Feld 4</p>
        				<?php include_once('../functions/php/dia.php'); ?>
        			</article>
        		</section>
        	</section>";
        

        Also kurz: Da wird HTML ausgegeben. Die Meta-Anweisung <?php include ...?> ergibt aber in HTML keinen Sinn. Bedenke, dass der Text so ausgegeben wird, wie er in der echo-Anweisung steht! Das ist also schon mal zum Scheitern verurteilt.

        wie mir grad aufgefallen ist, kann das nicht funktionieren da die dia.php an der Stelle in der ersten .php Datei nicht aufgerufen/eingebunden wird.

        Das ist die Konsequenz, richtig. Dafür steht die oben zitierte PHP-Anweisung nutzlos im HTML-Quellcode.

        include('dia.php')
        
        for($e = 0; $e < $count; $e++)
        {
        	...
        	$class_eintrag = '"eintrag"';
        	$class_zeile = '"eintrag_zeile"';
        	$class_eintrag_links = '"eintrag_links"';
        	$class_eintrag_rechts = '"eintrag_rechts"';
        	
        	
        	
        	echo "
        	<section class=$class_eintrag>
        		<section class=$class_zeile>
        			<article class=$class_eintrag_links>
        			<p>Feld 1 <br />                $ergebnis_s[0]:$ergebnis_s[1]:$ergebnis_s[2]:$ergebnis_p[1] , $col_name</p>
        			</article>
        			<article class=$class_eintrag_rechts>
        			<p>Feld 2</p>
        			</article>
        		</section>
        		<section class=$class_zeile>
        			<article class=$class_eintrag_links>
        				<p>Feld 3</p>
        			</article>
        			<article class=$class_eintrag_rechts>
        				<p>Feld 4</p>
        				echo "<img src='test.jpg' />";
                                        echo '<p>$gesamt</p>;
        			</article>
        		</section>
        	</section>";
        

        Besser. So kann es funktionieren. Für "ordentliches" Markup fehlen dann zwar einige Anführungszeichen bei den class-Attributen, aber damit kommt der Browser schon zurecht.

        Da klappt zwar die Ausgabe des Diagramms aber er erkennt den relativen Pfad zur .ttf nicht

        Wer ist "er"?

        Und bedenke, von welchem Verzeichnis eine relative Angabe ausgeht: Immer vom Verzeichnis des Scripts, das in der include-Hierarchie an oberster Stelle steht.

        Hab auch gerade herrausgefunden

        Gut. Den Herrn Aus suche ich nämlich auch manchmal.

        Kurz: wenn ich die dia.php direkt über ein Browser öffne wird die .ttf im selben Verzeichnis wie die dia.php gefunden. Und wenn die uebersicht.php die dia.php aufruft wird der Pfad nicht erkannt und es gibt eine Fehlermeldung.

        Sag ich doch: Die Pfadangaben passen nicht.

        Ciao,
         Martin

        1. Hey,

          Besser. So kann es funktionieren. Für "ordentliches" Markup fehlen dann zwar einige Anführungszeichen bei den class-Attributen, aber damit kommt der Browser schon zurecht.

          Was Fehlt da? Da stehen doch Anführungszeichen.

          $class_eintrag = ' >"< eintrag >"< ';
          ...
          <section class=$class_eintrag>
          

          Oder ist das falsch?

          Da klappt zwar die Ausgabe des Diagramms aber er erkennt den relativen Pfad zur .ttf nicht

          Wer ist "er"?

          Keine Ahnung, vielleicht der der sich meinen Kauderwelsch durchliest und daraus eine Anzeige bastelt.

          Und bedenke, von welchem Verzeichnis eine relative Angabe ausgeht: Immer vom Verzeichnis des Scripts, das in der include-Hierarchie an oberster Stelle steht.

          Achwas, das war mir noch garnicht bewusst dachte immer von dem Script welches gerade ausgeführt wird. Danke.

          Hab auch gerade herrausgefunden

          Gut. Den Herrn Aus suche ich nämlich auch manchmal.

          Ja, Er versteckt sich auch immer so gekonnt.

          Sag ich doch: Die Pfadangaben passen nicht.

          Ich dachte diese Möglichkeit ("../functions/php/arial.ttf") hatte ich ausprobiert. Anscheinend doch nicht. Das mit der include-Hierarchie war mir jedenfalls nicht klar. Pfad überarbeitet und Funktioniert. Vielen Dank.

          Gruß

          Jo

          1. Tach,

            Für "ordentliches" Markup fehlen dann zwar einige Anführungszeichen bei den class-Attributen, aber damit kommt der Browser schon zurecht.

            Was Fehlt da? Da stehen doch Anführungszeichen.

            $class_eintrag = ' >"< eintrag >"< ';
            ...
            <section class=$class_eintrag>
            

            ja, jetzt verstehe ich es auch. Trotzdem autschn.

            Erstens: Bitte setze keine Zeichen in Codebeispiele, die den Code entstellen würden. Auch nicht, wenn sie nur zur Hervorhebung dienen. Ich habe nämlich gerade überlegt, wie das mit den Kleiner- und Größer-Zeichen in Klassennamen funktionieren soll. Hab's dann nochmal mit dem vorherigen Posting verglichen, und tatsächlich, da war's richtig.
            Zweitens: Das ist kein empfohlenens Vorgehen. Die Anführungszeichen gehören nicht zum Klassennamen, sondern zum Markup drumherum. So sollte man das dann auch notieren - und dabei entweder kontextspezifisch maskieren, oder gleich unterschiedliche Anführungszeichen verwenden.

            Sag ich doch: Die Pfadangaben passen nicht.

            Ich dachte diese Möglichkeit ("../functions/php/arial.ttf") hatte ich ausprobiert. Anscheinend doch nicht. Das mit der include-Hierarchie war mir jedenfalls nicht klar. Pfad überarbeitet und Funktioniert.

            Kaum macht man's richtig, schon geht's. ;-)

            Vielen Dank.

            Keine Ursache.

            Fröhliches Schwitzen noch (hier bei etwa 30° in der Wohnung),
             Martin

            1. Hallo und guten Nachmittag,

              Kaum macht man's richtig, schon geht's. ;-)

              Hey, dss ist mein Spruch ;-P

              Fröhliches Schwitzen noch (hier bei etwa 30° in der Wohnung),

              Ich habe heute trotz Durchzug schon 35°C. Ohne wäre es in der oberen Etage noch mehr.
              Ich hab auch (hoffentlich) alle Kameras gefunden und zugeklebt :-O

              Grüße
              TS

              1. Hi,

                Kaum macht man's richtig, schon geht's. ;-)

                Hey, dss ist mein Spruch ;-P

                hinten anstellen, bitte. Bei mehr Bewerbern als Lizenzen entscheidet das Los.

                Fröhliches Schwitzen noch (hier bei etwa 30° in der Wohnung),

                Ich habe heute trotz Durchzug schon 35°C. Ohne wäre es in der oberen Etage noch mehr.

                Tja, ich hatte die Nacht über alle Fenster auf, die mit Fliegengitter ausgerüstet sind, und so hatte sich die Wohnung bis zum Morgen auf etwa 25° "abgekühlt". Kurz vor acht dann sämtliche Fenster und Rollläden zu. Hilft aber nur wenig. Die ungefähr 30m² große, direkt nach Süden gerichtete und um 45° geneigte Dachfläche fängt so viel Hitze auf ... Ich habe mal grob überschlagen, dass ich an einem heißen Sommertag sozusagen unter einer 50kW-Heizplatte sitze.

                Und die Dachziegel speichern die Hitze auch noch und geben sie über viele Stunden hinweg langsam wieder ab.

                Ich hab auch (hoffentlich) alle Kameras gefunden und zugeklebt :-O

                Hehe. Ich bin heute auch kostümiert. Als Adam in der Prä-Feigenblatt-Ära. ;-)
                Wobei ... ich glaube, der hatte weder Brille, noch Armbanduhr.

                So long,
                 Martin

                1. Hallo und guten Sanuanachmittag,

                  Ich habe mal grob überschlagen, dass ich an einem heißen Sommertag sozusagen unter einer 50kW-Heizplatte sitze.

                  Huuhh. Bei ca. 5-6 aktiven Sonnenstunden sind das 300kWh. Das entspricht ungefähr meinem Strombedarf für sechs Wochen.

                  Im Keller habe ich auch noch ca. 12°C. Ich habe schon mal überlegt, dass man die Wärme da hinunter schaffen müsste und speichern und die kühle Luft dafür hoch ins Schlafzimmer. Aber für eine echte Solarthermieanlage habe ich dann doch zuwenig solcher Sonnenstunden im Jahr. Noch lohnt sie sich nicht. Das wird erst was, wenn wir Bürger mit der Entsorgungskostenumlage für die Atommüllwerke belegt werden.

                  Grüße
                  TS

              2. Hallo,

                Kaum macht man's richtig, schon geht's. ;-)

                Hey, dss ist mein Spruch ;-P

                Du bist Dan?

                Gruß
                Kalk

                1. Hallo und guten Saunanachmittag,

                  Kaum macht man's richtig, schon geht's. ;-)

                  Hey, dss ist mein Spruch ;-P

                  Du bist Dan?

                  Nein. Ich bin Nummer Eins :-)

                  Bei mir heißt das eigentlichn auch:

                  Kaum macht man's richtig, schon funktioniert's
                  

                  Ist ja aber fast das Gleiche.

                  Grüße
                  TS

      2. Hallo und guten Nachmittag,

        Kurz: wenn ich die dia.php direkt über ein Browser öffne wird die .ttf im selben Verzeichnis wie die dia.php gefunden. Und wenn die uebersicht.php die dia.php aufruft wird der Pfad nicht erkannt und es gibt eine Fehlermeldung.

        Auch nur kurz ;-)

        Wenn die Datei 'arial.ttf' im selben Verzeichnis liegt, wie das Script, dass den Request bearbeitet (also nicht das include-Verzeichnis), dann wird sie, so wie Du sie angegeben hast, auch gefunden. Sonst mutss Du einen 'qualifizierten Pfad im Dateisystem' angeben. Das Hat also auch nichts mit der Document Root zu tun, außer, dass bei vielen Hostern die Scripte nicht rausgreifen dürfen aus dem 'DocRoot-Jail'. Das ist aber dann Einrichtungssache.

        Da der Browser nichts damit macht, sondern nur der Server, hat das auch mit dem Browser nichts zu tun.

        Grüße
        TS

    2. Hallo und guten Nachmittag Herr Autor ;-)

      [...]
      	imagejpeg($diagramm, "test.jpg");
      

      also halten wir mal fest: Dieses Script gibt eine JPEG-Bildressource aus. Wobei ich ehrlich gesagt noch den Header "Content-Type: image/jpeg" vermisse; ich weiß aber nicht, ob imagejpeg() das nicht möglicherweise von sich aus erledigt.

      Ja, es macht aus dem Pixelhaufen (hier 4 Bytes im Speicher pro Pixel) eine JPEG-Datei. Wenn man den Dateinamen weglässt, wird statt in eine Datei auf der Platte in die Standard-Ausgabe (also in diesem Fall der Kanal zum Browser) geschrieben.

      JPEG-Dateien enthalten keine HTTP-Header ;-)

      Wenn man die Datei also zum Browser schicken will, muss man vorher den passenden Header senden (setzen), wenn sie denn vom Browser auch als Bilddatei verstanden werden soll.

      Grüße
      TS

      1. Hallo,

        Hallo und guten Nachmittag Herr Autor ;-)

        du jetzt auch noch ... :-)

        also halten wir mal fest: Dieses Script gibt eine JPEG-Bildressource aus. Wobei ich ehrlich gesagt noch den Header "Content-Type: image/jpeg" vermisse; ich weiß aber nicht, ob imagejpeg() das nicht möglicherweise von sich aus erledigt.

        Ja, es macht aus dem Pixelhaufen (hier 4 Bytes im Speicher pro Pixel) eine JPEG-Datei. Wenn man den Dateinamen weglässt, wird statt in eine Datei auf der Platte in die Standard-Ausgabe (also in diesem Fall der Kanal zum Browser) geschrieben.

        Stimmt. Ich hatte völlig übersehen, dass Jo einen Dateinamen angegeben und somit tatsächlich eine Datei erzeugt hat, weil mir diese Verwendung zwar latent bekannt war, ich sie aber noch nie so angewendet habe. Ich habe die Daten immer mit imagejpeg() sofort an den anfragenden Client (über stdout) ausgegeben.

        JPEG-Dateien enthalten keine HTTP-Header ;-)

        Ach. Ach was.
        Aber JPEG-Header. Also nicht nur den reinen Pixelhaufen. ;-)

        Wenn man die Datei also zum Browser schicken will, muss man vorher den passenden Header senden (setzen), wenn sie denn vom Browser auch als Bilddatei verstanden werden soll.

        Das habe ich fast intuitiv immer getan, wenn ich eine der entsprechenden Funktionen aus der gdlib verwendet habe. Ich könnte mir trotzdem vorstellen, dass in den imagexxx-Funktionen wieder eine passende "Magie" steckt, die das für mich erledigt, wenn ich es nicht selbst mache.

        Ciao,
         Martin

        1. Hallo und guten Saunanachmittag,

          (mein Handtuch auf dem Stuhl ist schon wieder reif zum Auswringen)

          Ja, es macht aus dem Pixelhaufen (hier 4 Bytes im Speicher pro Pixel) eine JPEG-Datei. Wenn man den Dateinamen weglässt, wird statt in eine Datei auf der Platte in die Standard-Ausgabe (also in diesem Fall der Kanal zum Browser) geschrieben.

          JPEG-Dateien enthalten keine HTTP-Header ;-)

          Ach. Ach was.
          Aber JPEG-Header. Also nicht nur den reinen Pixelhaufen. ;-)

          Deshalb schrob ich ja auch: macht aus dem Pixelhaufen eine JPEG-Datei.
          Die unterliegt schließlich eigenen Formvorschriften :-P

          Grüße
          TS

  3. @@j4nk3y

    ich arbeite gerade an einem Kreisdiagramm welches durch php mittels Datanbankzugriff erstellt wird.

    Für dein Kreisdiagramm ist JPEG das völlig falsche Grafikfomat. Für Pixelgrafiken mit wenigen Farben und harten Farbwechseln sind PNG-8 (oder GIF) geeignet. [GIF-JPEG, GRAFIKFORMAT]

    Aber auch PNG (GIF) ist allenfalls zweite Wahl. Pixelgrafiken sind unscharf (oder groß). Hier solltest du eine Vektorgrafik (SVG) einsetzen.

    Das hat auch den Vorteil, dass SVG ein XML-Format ist, das du ebenso wie HTML direkt mit PHP in dein HTML-Dokument schreiben kannst und dafür auch keine Grafikfunktionen brauchst.

    LLAP 🖖

    --
    Ist diese Antwort anstößig? Dann könnte sie nützlich sein.