Bitmap generator

bitmap generator

I needed to build a series of regular bitmaps such as a row of 10 4x4 squares and a 10x10 grid of 4x4 squares. I could have used a bitmap editor but it would be labor-intensive and I preferred to generate the bitmap programmatically. A single proc is used to convert strings of 1's and 0's into bitmaps.

The width of the bitmap is defined by the length of the first argument. Successive lines are filled with zeros if necessary to match the length.

gen_bitmap

proc gen_bitmap { args } { 
   set height [ llength $args ]
   set width  [ string length [ lindex $args 0 ]]
   set setbx "#define bullet_width $width\n#define bullet_height $height \n"
   append setbx "static char bullet_bits = \{\n"
   foreach arg $args {
      if { [ regexp {L([0-9]+)} $arg dummy argnum ] } {
         set arg [ lindex $args $argnum-1 ]
      }
      puts "$arg"
      set i 0
      set res 0
      append arg [ string repeat 0 [ expr $width - [ string length $arg ]]]
      append arg "0000000"
      foreach ch [ split $arg "" ] {
         if { $ch } {
            incr res [ expr 1 << $i % 8 ]
            # puts "ch $ch $i $res"
         }
         incr i
         if { ! ( $i % 8 ) } {
            lappend bits [ format "0x%02x" $res ]
            set res 0
         }
      }
   }
   append setbx [ join $bits ", " ]
   append setbx "\}"
   return $setbx
}

Examples

catch { destroy .bitmaps }
toplevel .bitmaps
wm title .bitmaps Bitmaps

canvas .bitmaps.c -width 400 -height 300 -bg white
pack .bitmaps.c 
set C .bitmaps.c

set bm_1k_s [ gen_bitmap \
00111111111111111111111111111111111111111111111111100 \
01111111111111111111111111111111111111111111111111110 \
11111111111111111111111111111111111111111111111111111 \
11111111111111111111111111111111111111111111111111111 \
11111111111111111111111111111111111111111111111111111 \
11111111111000011111100000001111000000001111111111111 \
11111111110000011111110000011111100000011111111111111 \
11111111100000011111111000011111111000011111111111111 \
11111111000000011111111000011111110000111111111111111 \
11111111111000011111111000011111100001111111111111111 \
11111111111000011111111000011111000011111111111111111 \
11111111111000011111111000011110000111111111111111111 \
11111111111000011111111000011100001111111111111111111 \
11111111111000011111111000011000011111111111111111111 \
11111111111000011111111000000001111111111111111111111 \
11111111111000011111111000000001111111111111111111111 \
11111111111000011111111000011000011111111111111111111 \
11111111111000011111111000011100001111111111111111111 \
11111111111000011111111000011110000111111111111111111 \
11111111111000011111111000011111000011111111111111111 \
11111111111000011111111000011111100001111111111111111 \
11111111111000011111111000011111110000111111111111111 \
11111111110000001111111000011111111000001111111111111 \
11111111100000001111111000011111100000001111111111111 \
11111111000000000111110000000111100000000011111111111 \
11111111111111111111111111111111111111111111111111111 \
11111111111111111111111111111111111111111111111111111 \
11111111111111111111111111111111111111111111111111111 \
01111111111111111111111111111111111111111111111111110 \
00111111111111111111111111111111111111111111111111100 \
]

image create bitmap bm_1k_red -data $bm_1k_s -fore red
$C create image 50 25 -image bm_1k_red

image create bitmap bm_1k_blue -data $bm_1k_s -fore blue
$C create image 150 25 -image bm_1k_blue


# This generates 10 rows of 10 diamonds

set pat1 "00100"
set pat2 "01110"
set pat3 "11111"

set line1 [ string repeat $pat1 10 ]
set line2 [ string repeat $pat2 10 ]
set line3 [ string repeat $pat3 10 ]

# L1 is replaced by the 1st arg, L2 by the second arg, etc.
set bm_diamonds [ gen_bitmap \
$line1 $line2 $line3 $line2 $line1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 ]

image create bitmap diamonds_blue -data $bm_diamonds   -fore blue

$C create image  50 100  -anchor n -image diamonds_blue 
$C create image 150 150  -anchor n  -image diamonds_blue

# 4 rows of 10 diamonds
set bm_diamonds [ gen_bitmap \
$line1 $line2 $line3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 \
L1 L2 L3 L2 L1 ]

image create bitmap diamonds_red -data $bm_diamonds   -fore red

$C create image 150 100 -anchor n  -image diamonds_red
$C create image  50 150 -anchor n   -image diamonds_red


# 24 bitmaps - each a row of 1 to 24 4x4 squares

set curbase 24
for { set i 1 } { $i <= $curbase } { incr i } {
   set bmi [ string repeat "11110" $i ]
   set zri [ string repeat "00000" $i ]
   set bmdata [ gen_bitmap $bmi $bmi $bmi $bmi $zri ]
   image create bitmap blocks$i -data $bmdata -fore blue
}

for { set i 1 } { $i <= $curbase } { incr i } {
   $C create image 200 [ expr $i * 10 + 10 ] -anchor w -image blocks$i 
}