查阅了相关资料后我终于把这个函数修改出来啦。该函数可以实现以 PNG 格式将 EAN-13/UPC 条码输出到浏览器中。代码是在 PHP 生成 EAN-13 标准条形码 - 脚本之家 的基础上修正、重写的,原来的代码中出现了一些致命错误,在下面的代码中都已修复。另外由于最后一位是校验位,需要计算求得,为了方便使用我将代码改为输入 12 或 13 位均可识别,12 位自动补全,13 位自动覆盖。 原始的代码错误主要有:
<?php
/**
* EAN-13条码图片生成函数
*
* @author mowchan
* @version 15.0722
* @example EAN_13('6901234567890', 2, 80)
* @param code:条码号, width:一个单元的宽度, height:条码高
*/
function EAN_13($code, $width, $height)
{
/* 定义字符集选择规则 */
$Guide = array(
'LLLLLL',
'LLGLGG',
'LLGGLG',
'LLGGGL',
'LGLLGG',
'LGGLLG',
'LGGGLL',
'LGLGLG',
'LGLGGL',
'LGGLGL'
);
/* 定义二进制子集 */
$Encode = array(
"L" => array(
'0001101',
'0011001',
'0010011',
'0111101',
'0100011',
'0110001',
'0101111',
'0111011',
'0110111',
'0001011'
),
"G" => array(
'0100111',
'0110011',
'0011011',
'0100001',
'0011101',
'0111001',
'0000101',
'0010001',
'0001001',
'0010111'
),
"R" => array(
'1110010',
'1100110',
'1101100',
'1000010',
'1011100',
'1001110',
'1010000',
'1000100',
'1001000',
'1110100'
)
);
/* 定义辅助字符二进制 */
$start = '101';
$center = '01010';
$ends = '101';
/* 检验输入编码位数 */
if (strlen($code) == 12 || strlen($code) == 13) {
}else{
die("请输入12或13位的EAN-13编码");
}
/* 计算校验位数值 */
$lsum = 0;
$rsum = 0;
for ($i = 0; $i < (strlen($code) - 1); $i++) {
if ($i % 2) {
$lsum += (int) $code[$i];
} else {
$rsum += (int) $code[$i];
}
}
$tsum = $lsum * 3 + $rsum;
$lastcode = 10 - ($tsum % 10);
if ($lastcode == 10){
$code[12] = 0;
}else{
$code[12] = $lastcode;
}
/* 转换成二进制 */
$barcode = $start;
for ($i = 1; $i <= 6; $i++) {
$barcode .= $Encode[$Guide[$code[0]][($i - 1)]][$code[$i]];
}
$barcode .= $center;
for ($i = 7; $i < 13; $i++) {
$barcode .= $Encode['R'][$code[($i)]];
}
$barcode .= $ends;
/* 绘制条码 */
$img = ImageCreate($width * 95 + 60, $height + 30);
$fg = ImageColorAllocate($img, 0, 0, 0);
$bg = ImageColorAllocate($img, 255, 255, 255);
ImageFilledRectangle($img, 0, 0, $width * 95 + 60, $height + 60, $bg);
$shift = 10;
for ($x = 0; $x < strlen($barcode); $x++) {
if (($x < 4) || ($x >= 45 && $x < 50) || ($x >= 92)) {
$sh = 10;
} else {
$sh = 0;
}
if ($barcode[$x] == '1') {
$color = $fg;
} else {
$color = $bg;
}
ImageFilledRectangle($img, ($x * $width) + 30, 5, ($x + 1) * $width + 29, $height + 5 + $sh, $color);
}
/* 添加可读标签 */
ImageString($img, 5, 20, $height + 5, $code[0], $fg);
for ($x = 0; $x < 6; $x++) {
ImageString($img, 5, $width * (8 + $x * 6) + 30, $height + 5, $code[$x + 1], $fg);
ImageString($img, 5, $width * (53 + $x * 6) + 30, $height + 5, $code[$x + 7], $fg);
}
/* 输出浏览器标签格式 */
header("Content-Type: image/png");
ImagePNG($img);
}
?>
上面的代码最终输出的数字标签是用系统默认的字体,效果不是很好,若要获得真实的 EAN-13 的字体效果,需要使用OCR-B 10 BT.ttf
字体文件。下面代码是结合使用字体文件需要修改的内容:
<?php
/* 添加可读标签 */
ImageTTFText($img, 15, 0, 12, $height + 22, $fg, 'OCR-B 10 BT.ttf', $code[0]);
for ($x = 0; $x < 6; $x++) {
ImageTTFText($img, 15, 0, $width * (8 + $x * 7) + 22, $height + 22, $fg, 'OCR-B 10 BT.ttf', $code[$x + 1]);
ImageTTFText($img, 15, 0, $width * (56 + $x * 7) + 18, $height + 22, $fg, 'OCR-B 10 BT.ttf', $code[$x + 7]);
}
?>