Total Tayangan Halaman

Jumat, 07 Agustus 2009

Barcode CODE 128 dengan PHP

Mengapa menggunakan CODE 128, bukan yang lain?
Karena dapat digunakan untuk kombinasi antara alfabet dan numerik, kode ini juga dapat digunakan untuk 128 karakter ASCII, panjangnya pun bisa suka-suka (ini dia yang saya cari).

Apa dan siapa CODE 128?
Code 128 terdiri atas 6 seksi, yaitu

  1. Quiet Zone
  2. Start Character
  3. Encoded Data
  4. Check Character
  5. Stop Character
  6. Quiet Zone
Quiet Zone pada seksi 1 dan 6 adalah sama, yakni spasi kosong dengan ketebalan 10.
Check Character pada seksi 4 adalah checksum modulo 103 dari start character + (posisi bar * ketebalan)
Stop Character pada seksi 5 adalah 2331112 (2 hitam, 3 putih, 3 hitam, 1 putih, dst...)

Seksi 2 dan 3?
Code 128 memiliki 3 macam kode, yaitu A, B dan C. Saya hanya menggunakan kode B dan C. Kode B untuk alfabet dan numerik tunggal, sedangkan kode C untuk numerik ganda, misal: 00, 12, 99. Untuk setiap penggunaan kode B diawali dengan 211214 dan kode C diawali dengan 211232.
Misal:
aku9 -> [quiet zone][start B][bar a][bar k][bar u][bar 9][check character][stop][quiet zone]
0122 -> [quiet zone][start C][bar 01][bar 22][check character][stop][quiet zone]
ak50 -> [quiet zone][start B][bar a][bar k][start C][bar 22][check character][stop][quiet zone]

Perhatian:
Penggunaan kode B dan kode C bebas, terserah kita, tetapi penggunaan yang salah bisa mengakibatkan barcode lebih panjang.
Misal:
12 -> [quiet zone][start B][bar 1][bar 2][check character][stop][quiet zone]
seharusnya
12 -> [quiet zone][start C][bar 12][check character][stop][quiet zone]
Pada program ini sudah dilengkapi dengan optimasi, yaitu jika ada karakter numerik dengan jumlah genap yang lebih dari 3 dan sebelumnya adalah kode B, maka menggunakan kode C, sisanya menggunakan kode B.
a12 -> [quiet zone][start B][bar a][bar 1][bar 2][check character][stop][quiet zone]
a12 -> [quiet zone][start B][bar a][start C][bar 12][check character][stop][quiet zone]
baris 1 dan 2 sama lebarnya

a1234 -> [quiet zone][start B][bar a][bar 1][bar 2][bar 3][bar 4][check character][stop][quiet zone]
a1234 -> [quiet zone][start B][bar a][start C][bar 12][bar 34][check character][stop][quiet zone]
baris 1 lebih panjang daripada baris 2

Oke, inilah dia kode lengkapnya, disertai contoh pemakaian:
<?
class barcode128
{ var $start_b = array("value" => 104, "bar" => "211214");
var $start_c = array("value" => 105, "bar" => "211232");
var $code_b2c = array("value" => 99, "bar" => "113141");
var $code_c2b = array("value" => 100, "bar" => "114131");
var $stop = "2331112";
var $quiet_zone_start = "0901";
var $quiet_zone_end = "901";
var $code = array("212222", "222122", "222221", "121223", "121322",
"131222", "122213", "122312", "132212", "221213",
"221312", "231212", "112232", "122132", "122231",
"113222", "123122", "123221", "223211", "221132",
"221231", "213212", "223112", "312131", "311222",
"321122", "321221", "312212", "322112", "322211",
"212123", "212321", "232121", "111323", "131123",
"131321", "112313", "132113", "132311", "211313",
"231113", "231311", "112133", "112331", "132131",
"113123", "113321", "133121", "313121", "211331",
"231131", "213113", "213311", "213131", "311123",
"311321", "331121", "312113", "312311", "332111",
"314111", "221411", "431111", "111224", "111422",
"121124", "121421", "141122", "141221", "112214",
"112412", "122114", "122411", "142112", "142211",
"241211", "221114", "413111", "241112", "134111",
"111242", "121142", "121241", "114212", "124112",
"124211", "411212", "421112", "421211", "212141",
"214121", "412121", "111143", "111341", "131141",
"114113", "114311", "411113", "411311", "113141",
"114131", "311141", "411131"
);
var $bar_height;
var $pattern;
var $checksum;
var $bar;
var $input;


function barcode128($height=50)
{ $this->bar_height = $height;
}


function _barcode($inp="")
{ $this->input = $inp;
$this->initialize();
return $this->_draw_barcode();
}


function barcode($inp="")
{ $this->input = $inp;
$this->initialize();
$this->draw_barcode();
}


function debug_barcode($inp="")
{ $this->input = $inp;
$this->initialize();
$this->debug_draw_barcode();
}


function reset()
{ $this->pattern = "";
$this->checksum = "";
$this->bar = "";
}


function initialize()
{ $this->reset();
//create a pattern to decide which codefication applied (code b or code c)
$prev_char = "x";
$count_char = 0;
for ($i = 0; $i < strlen($this->input); $i++)
{ if ($this->is_digit(substr($this->input, $i, 1))) $cur_char = "d"; else $cur_char = "a";
if ($prev_char == "x")
{ $count_char = 1;
$this->pattern[] = $cur_char;
}
elseif ($prev_char == $cur_char)
$count_char++;
else
{ if (($prev_char == "a") or ($prev_char == "d" and $count_char <= 3))
{ $temp_count += $count_char;
$count_char = 1;
}
elseif ($count_char % 2 == 0)
{ if ($temp_count > 0) $this->pattern[] = $temp_count;
$this->pattern[] = $count_char;
$temp_count = 0;
$count_char = 1;
}
elseif ($prev_char == "d" and $count_char % 2 == 1)
{ if ($temp_count > 0) $this->pattern[] = $temp_count;
$this->pattern[] = $count_char - 1;
$temp_count = 0;
$count_char = 2;
}
}
$prev_char = $cur_char;
}
if (($prev_char == "a") or ($prev_char == "d" and $count_char <= 3))
{ $this->pattern[] = $temp_count + $count_char;
}
elseif ($count_char % 2 == 0)
{ if ($temp_count > 0) $this->pattern[] = $temp_count;
$this->pattern[] = $count_char;
}
elseif ($prev_char == "d" and $count_char % 2 == 1)
{ if ($temp_count > 0) $this->pattern[] = $temp_count;
$this->pattern[] = $count_char - 1;
$this->pattern[] = 1;
}


//save graph info and count checksum
if ($this->pattern[0] == "a")
{ $this->checksum = $this->start_b["value"];
$this->bar = $this->start_b["bar"];
$idx_code = 0;
}
else
{ $this->checksum = $this->start_c["value"];
$this->bar = $this->start_c["bar"];
$idx_code = 1;
}
$idx_this->input = 0;
$idx_checksum = 1;
for ($idx_pattern = 1; $idx_pattern <= count($this->pattern); $idx_pattern++)
{ if ($idx_code % 2 == 0)
{ for($i = 0; $i < $this->pattern[$idx_pattern]; $i++)
{ $this->checksum += $idx_checksum++ * $this->ascii2idx_code(substr($this->input, $idx_this->input, 1));
$this->bar .= $this->code[$this->ascii2idx_code(substr($this->input, $idx_this->input++, 1))];
}
if ($idx_pattern != count($this->pattern))
{ $this->checksum += $idx_checksum++ * $this->code_b2c["value"];
$this->bar .= $this->code_b2c["bar"];
}
}
else
{ for($i = 0; $i < $this->pattern[$idx_pattern]; $i+=2)
{ $this->checksum += $idx_checksum++ * intval(substr($this->input, $idx_this->input, 2));
$this->bar .= $this->code[intval(substr($this->input, $idx_this->input, 2))];
$idx_this->input += 2;
}
if ($idx_pattern < count($this->pattern) - 1)
{ $this->checksum += $idx_checksum++ * $this->code_c2b["value"];
$this->bar .= $this->code_c2b["bar"];
}
}
$idx_code++;
}
$this->checksum %= 103;
$this->bar .= $this->code[intval($this->checksum)];
$this->bar .= $this->stop;
$this->bar = $this->quiet_zone_start.$this->bar.$this->quiet_zone_end;
}


function is_digit($char)
{ if ($char >= "0" and $char <= "9") return true; else return false;
}


function ascii2idx_code($char)
{ return ord($char) - 32;
}


function _draw_barcode()
{ $ret = "";
for ($i = 0; $i < strlen($this->bar); $i++)
if ($i % 2 == 0) $ret .= "<img src='black.png' width='".(substr($this->bar,$i,1))."' height='$this->bar_height'>"; else $ret .= "<img src='white.png' width='".(substr($this->bar,$i,1))."' height='$this->bar_height'>";
return $ret;
}


function draw_barcode()
{ for ($i = 0; $i < strlen($this->bar); $i++)
if ($i % 2 == 0) echo "<img src='black.png' width='".(substr($this->bar,$i,1))."' height='$this->bar_height'>"; else echo "<img src='white.png' width='".(substr($this->bar,$i,1))."' height='$this->bar_height'>";
}


function debug_draw_barcode()
{ for ($i = 0; $i < strlen($this->bar); $i++)
if ($i % 2 == 0) echo substr($this->bar,$i,1); else echo substr($this->bar,$i,1);
}
}


/* example
$x = new barcode128;
$inp = "pramudita sholikhah azzahra";
echo "$inp<br/>";
$x->barcode($inp);
*/
?>




<?
$x = new barcode128;
$inp = "test";
echo "$inp<br/>";
$x->debug_barcode($inp);
?>

Tidak ada komentar: