Tk avancé - Créer une bitmap

 

Tk avancé - Créer une image bitmap


Structure d'une image bitmap

Une image bitmap est définie par deux couleurs et deux matrice booléennes :

Les deux matrices ont la même taille et chaque booléen correspond à un pixel de l'image.

Un pixel de l'image est transparent ou opaque :

Un pixel opaque appartient à l'arrière-plan ou à l'avant-plan :


Format des couleurs

Les couleurs ont deux types de formats :

Les composants d'une couleur sous forme hexadécimale peuvent comporter un, deux, trois ou quatre digits (le même nombre pour chaque composant) :

C'est la forme #RRGGBB la plus courante car chaque composant doit avoir une valeur entre 0 et 255 (bornes comprises).

La valeur #000000 correspond au noir. La valeur #ffffff correspond au blanc.

Quand les trois composants sont égaux, il s'agit d'un gris.


Format des matrices

Une image de dimension 15 x 4 correspond à une matrice :

  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx

Chaque ligne de la matrice correspond à une ligne de l'image.

Chaque bit de la matrice correspond à un pixel de l'image.


Encodage

Pour encoder la matrice et créer la valeur d'une option -data ou -maskdata

  xxxxxxxx xxxxxxx
  xxxxxxxx xxxxxxx
  xxxxxxxx xxxxxxx
  xxxxxxxx xxxxxxx

Le dernier groupe peut comporter moins de 8 bits.

Le bit de gauche correspond au poids faible de la valeur (on renverse l'ordre des bits)

  01101001 -> 10010110 = 0x96

Voici le script qui fait la transformation d'un groupe de 8 bits :

  proc digit2hexa {bits} \
  {
    set hexa 0
    while {$bits ne ""} \
    {
      set bit [string index $bits end]
      set bits [string range $bits 0 end-1]
      incr hexa $hexa ;# multiplication par deux
      incr hexa $bit ;# ajout du bit
    }
    return 0x[format %2.2x $hexa]
  }
  puts [digit2hexa 01101001]

0x96

Dont voici un exemple :

  #define question_width 17
  #define question_height 27
  static unsigned char question_bits[] = {
   0xf0, 0x0f, 0x00, 0x58, 0x15, 0x00, 0xac, 0x2a, 0x00, 0x56, 0x55, 0x00,
   0x2b, 0xa8, 0x00, 0x15, 0x50, 0x01, 0x0b, 0xa0, 0x00, 0x05, 0x60, 0x01,
   0x0b, 0xa0, 0x00, 0x05, 0x60, 0x01, 0x0b, 0xb0, 0x00, 0x00, 0x58, 0x01,
   0x00, 0xaf, 0x00, 0x80, 0x55, 0x00, 0xc0, 0x2a, 0x00, 0x40, 0x15, 0x00,
   0xc0, 0x02, 0x00, 0x40, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x40, 0x01, 0x00,
   0xc0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xc0, 0x02, 0x00,
   0x40, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x00, 0x01, 0x00};

Le nom de l'image est "question" que l'on retrouve dans les trois premières lignes (ce nom doit être conforme à la syntaxe C).

Les valeurs booléennes sont transformées comme indiqué ci-dessus et assemblées dans une constante de tableau C.

Rappel : Les options -data et -maskdata ont le même format.


Exemple complet

Voici la bitmap à créer : http://wfr.tcl.tk/fichiers/images/ulis/question.xbm

Voici son image sous forme de bits :

  00001111111100000
  00011010101010000
  00110101010101000
  01101010101010100
  11010100000101010
  10101000000010101
  11010000000001010
  10100000000001101
  11010000000001010
  10100000000001101
  11010000000011010
  00000000000110101
  00000000111101010
  00000001101010100
  00000011010101000
  00000010101010000
  00000011010000000
  00000010100000000
  00000011010000000
  00000010100000000
  00000011010000000
  00000000000000000
  00000001100000000
  00000011010000000
  00000010100000000
  00000011010000000
  00000000100000000

Voici la procédure de transformation :

  proc bits2bitmap {name lines} \
  {
    set width [string length [lindex $lines 0]]
    set height [llength $lines]
    set list [list]
    foreach line $lines \
    {
      while {$line ne ""} \
      {
        # decoupage par groupe de 8
        set bits [string range $line 0 7]
        set line [string range $line 8 end]
        # digit2hexa
        set hexa 0
        while {$bits ne ""} \
        {
          set bit [string index $bits end]
          set bits [string range $bits 0 end-1]
          incr hexa $hexa ;# multiplication par deux
          incr hexa $bit ;# ajout du bit
        }
        lappend list 0x[format %2.2x $hexa]
      }
    }
    # mise en forme
    set result ""
    append result "#define ${name}_width $width\n"
    append result "#define ${name}_height $height\n"
    append result "static unsigned char ${name}_bits[] = {\n"
    append result [join $list ", "]
    append result "};"
    return $result
  }

Voici l'utilisation de la bitmap :

  package require Tk
  set data [bits2bitmap question $data]
  set image [image create bitmap -data $data]
  label .l -image $image
  grid .l -padx 10 -pady 10


Exercice

Faire une bitmap et l'utiliser.


Voir Aussi


Catégorie Cours | Catégorie Encyclopédie Tk