PHP Image

Dessiner en Php avec GD

Courant 2007, j'ai créé une classe de dessin en PHP appelée PHPImage. Cette classe utilise GD2 et PHP5 et m'aide à dessiner facilement des images en PHP.

Il faut voir cette classe comme un wrapper intelligent de GD avec des fonctionnalités très avancées.

Par exemple, avec cette classe, vous pouvez définir des couleurs de manière très simple comme 'red 50%' pour un rouge transparent à 50% au lieu de devoir faire des imagecolorallocate à chaque fois avant l'utilisation de la couleur...

Cela permet d'économiser beaucoup de code inutile pour ce concentrer sur l'essentiel : ce que vous voulez dessiner.

Cette classe fait plus de 5000 lignes de code et plus de 160 Ko... ça représente presque 1 mois à temps plein de boulot.

Certaines primitives graphiques ont été complètement ré-écrites comme drawfilledpolygon. GD 2 permet de le faire mais il y a des erreurs au pixel près dans le dessin de la forme, en plus cela gère mal la transparence. Du coup, j'ai utilisé la technique de scanline pour remplir le polygone. Notez que l'implémentation varie un peu de la théorie pour des raisons de performance et de gestion de la transparence etc...

Pré-requis

Gérer les images en cache

PHPImage est parfaitement adaptée à une gestion propre d'images en cache avec des headers au poil ;)

Exemple d'utilisation de ce système de cache

<?php
$image = new PHPImage();
$image->cachetime = 86400*365*10; // 10 years
if($image->cacheok($source, $cached_image)) {
    $image->display($cached_image);
}
else {
    $image->loadfromfile($source);
    // put here your image processing
    // it can be : resize, crop, effects,...
    $image->display($cached_image);
}

Exemple de masque alpha

<?php
$image = new PHPImage('php.gif');
$mask = new PHPImage('mask.png');
$image->mask($mask);
$mask->destroy();
$image->format = 'png';
$image->display();

Exemple de masque alpha

<?php
$image = new PHPImage(120, 280);
$image->drawfilledrectangle(5, 5, 35, 35, 'black', 'all(none, 11)');
$image->drawfilledrectangle(45, 5, 75, 35, 'blue', 'all(empty, 11)');
$image->drawfilledrectangle(85, 5, 115, 35, 'red', 'all(biseau, 11)');

$image->drawfilledrectangle(5, 45, 35, 75, 'black', 'all(biseau2, 11)');
$image->drawfilledrectangle(45, 45, 75, 75, 'blue', 'all(biseau3, 11)');
$image->drawfilledrectangle(85, 45, 115, 75, 'red', 'all(biseau4, 11)');

$image->drawfilledrectangle(5, 85, 35, 115, 'black', 'all(round, 11)');
$image->drawfilledrectangle(45, 85, 75, 115, 'blue', 'all(round2, 11)');
$image->drawfilledrectangle(85, 85, 115, 115, 'red', 'all(curve, 11)');

$image->drawfilledrectangle(5, 125, 35, 155, 'black', 'all(curve2, 11)');
$image->drawfilledrectangle(45, 125, 75, 155, 'blue', 'all(curve3, 11)');
$image->drawfilledrectangle(85, 125, 115, 155, 'red', 'all(curve4, 11)');

$image->drawfilledrectangle(5, 165, 35, 195, 'black', 'all(curve5, 11)');
$image->drawfilledrectangle(45, 165, 75, 195, 'blue', 'all(curve6, 11)');
$image->drawfilledrectangle(85, 165, 115, 195, 'red', 'all(trait, 11)');

$image->drawfilledrectangle(5, 205, 35, 235, 'black', 'all(trait2, 11)');
$image->drawfilledrectangle(45, 205, 75, 235, 'blue', 'all(trait3, 11)');
$image->drawfilledrectangle(85, 205, 115, 235, 'red', 'all(round2+curve, 11)');

$image->drawfilledrectangle(5, 245, 35, 275, 'black', 'all(curve5+curve6, 11)');
$image->drawfilledrectangle(45, 245, 75, 275, 'blue', 'all(round%2+round2, 11)');
$image->drawfilledrectangle(85, 245, 115, 275, 'red', 'all(trait2+trait, 11)');
$image->format = 'png';
$image->display();

Exemple avec Héritage

<?php
class MyClass extends PHPImage {
    function makeframe($text, $forecolor, $bgcolor, $corner, $fontsize) {
        list($w, $h) = $this->gettextbox($text, $fontsize);
        if ($w > $h) {
            $margin = round(0.30*$h);
        } else {
            $margin = round(0.30*$w);
        }
        $w += 2*$margin;
        $h += 2*$margin;
        $this->create($w, $h);
        $this->drawrectanglewh(0, 0, $w, $h, $forecolor, 1, 'solid', 'all('.$corner.', '.$margin.')');
        $this->fill($w/2, $h/2, $bgcolor);
        $this->writetext('50%', '50%', $text, $fontsize, 0, $forecolor, 'center', 'center');
    }
}

$image = new MyClass();
$image->fontfile = '../methods/verdana.ttf';
$image->makeframe("The really true\nsolution is : 42 ...", 'gold', 'black', 'curve', 14);
$image->format = 'png';
$image->display();

Liens