Dessiner un damier à la Photoshop

C'est assez ennuyeux, lorsque l'on redimensionne des images avec la bibliothèque GD, de découvrir nos images transparentes sur un fond noir. C'est d'autant plus ennuyeux quand l'image en question est elle même en noir, comme par exemple du texte sur un fond transparent. Du coup on y voit plus rien et c'est tout nul.

Pour votre bonheur de créateur de miniatures, voici une fonction tirée de ma classe WdImage qui vous permettra de dessiner des damiers comme sous Photoshop.

Je sais, c'est chouette.

Quelques exemples

Dans les exemples suivants, $image est une ressource image créée avec la fonction imagecreatetruecolor(). $w représente sa largeur et $h sa hauteur.

Un damier de base

Avec le code suivant, nous allons créer un damier tout simple :

<?php

WdImage::drawGrid($image00$w - 1$h - 1);

drawGrid 1

Une moitié pour mettre en valeur la différence

Puisque nous pouvons définir les coordonnées du damier, autant faire un petit test pour voir la différence :

<?php

WdImage::drawGrid($image$w / 2 - 10$w - 1$h - 1);

drawGrid 2

Taille sans importance

Par défaut, la taille du damier est fixée à medium, ce qui correspond à des cases de 8 pixels de côté. En utilisant le paramètre size vous pouvez définir la taille du damier. Pour se faire, vous pouvez utiliser une des valeurs prédéfinies : small, medium ou large qui correspondent aux tailles 4, 8 et 16. Vous pouvez bien sûr spécifier la taille que vous désirer avec un entier : 2, 32, 64…

<?php

WdImage::drawGrid($image00$w - 1$h - 1'large');

drawGrid 3

Des couleurs funkys

Les couleurs par défaut du damier ne sont pas toujours adaptées pour mettre en valeur une image. Le paramètre color1 vous permet de changer la première couleur du damier, ou d'utiliser un des schémas de couleurs pré-définis. Ce sont les même que sous Photoshop, à savoir : light, medium, dark, red, orange, green, blue et purple.

<?php

WdImage::drawGrid($image00$w - 1$h - 1'medium''dark');

drawGrid 4

Enfin, le paramètre color2 vous permet de modifier la seconde couleur utilisée pour dessiner le damier :

<?php

WdImage::drawGrid($image00$w - 1$h - 1'medium'0xFF00FF0x00FF00);

drawGrid 5

La méthode en question

Voici donc un extrait de la classe WdImage, contenant la méthode drawGrid() ainsi que la méthode allocateColor() qui est utilisée pour allouer les couleurs.

À noter que les couleurs peuvent être spécifiées en hexadécimal 0xFFFFFF ou sous forme de tableau array(255, 255, 255). Les définissions CSS sont normalement supportées mais on été désactivées pour les besoins de la démonstration. La classe WdCSS ou sa méthode decodeColor() feront sans doute l'objet d'un prochain article.

<?php

class WdImage
{
    public static function drawGrid($image$x1$y1$x2$y2$size=4$color1=0xFFFFFF$color2=0xCCCCCC)
    {
        #
        # resolve size
        #
            
        if (is_string($size))
        {
            static $sizes = array
            (
                'none' => 0,
                'small' => 4,
                'medium' => 8,
                'large' => 16
            );
            
            if (isset($sizes[$size]))
            {
                $size = $sizes[$size];
            }
            else
            {
                $size = 4;
            }
        }

        #
        # resolve colors
        #
        
        if (is_string($color1))
        {
            static $color_schemes = array
            (
                'light' => array(0xffffff0xcccccc),
                'medium' => array(0x9999990x666666),
                'dark' => array(0x3333330x666666),
                'red' => array(0xffffff0xffcccc),
                'orange' => array(0xffffff0xffd8bd),
                'green' => array(0xffffff0xcce4cc),
                'blue' => array(0xffffff0xcce0f8),
                'purple' => array(0xffffff0xdcccf8)
            );
            
            if (isset($color_schemes[$color1]))
            {
                $scheme = $color_schemes[$color1];
            
                $color1 = $scheme[0];
                $color2 = $scheme[1];
            }
        }
        
        #
        # allocate colors
        #
        
        $c1 = self::allocateColor($image$color1);
        $c2 = self::allocateColor($image$color2);
        
        #
        # draw grid
        #
        
        if ($size)
        {
            #
            # draw grid, line by line, square by square
            #
            
            for ($j = $y1$b = 0 ; $j < $y2 ; $j += $size$b++)
            {
                for ($i = $x1$a = 0 ; $i < $x2 ; $i += $size$a++)
                {
                    imagefilledrectangle
                    (
                        $image,
                        
                        $i$j,
                        max($i + $size$x2),
                        max($j + $size$y2),
                        
                        ($a % 2) ? $c1 : $c2
                    );
                }
                
                #
                # in order to have a nice pattern,
                # after each line is drawn we switch color 1 and color 2
                #
    
                $t = $c1;
                $c1 = $c2;
                $c2 = $t;
            }
        }
        else
        {
            #
            # grid size is 0, we simply draw a rectangle with color 1
            #
        
            imagefilledrectangle($image$x1$y1$x2$y2$c1);
        }
    }
    
    public static function allocateColor($image$color)
    {
        #
        # use WdCSS class to decode CSS colors definition (#FFF, rgb(), white)
        #

//      if (is_string($color))
//      {
//          $color = WdCSS::decodeColor($color);
//      }

        if (is_array($color))
        {
            return imagecolorallocate
            (
                $image$color[0]$color[1]$color[2]
            );
        }
        else if (is_numeric($color))
        {
            return imagecolorallocate
            (
                $image($color & 0xFF0000) >> 16($color & 0x00FF00) >> 8($color & 0x0000FF)
            );
        }
        else
        {
            return imagecolorallocate
            (
                $image128128128
            );
        }
    }
}

Laisser un commentaire

Un commentaire

Karim
Karim

Hey ! Sympa comme idée :) Sinon aussi on peut conserver la transparence pour les PNG et les GIF avec GD (en prenant le problème dans un autre sens). Mais c sur que si on veut en faire un JPEG ta solution est tres sympa :)