EAN-13条码图片生成函数

查阅了相关资料后我终于把这个函数修改出来啦。该函数可以实现以 PNG 格式将 EAN-13/UPC 条码输出到浏览器中。代码是在 PHP 生成 EAN-13 标准条形码 - 脚本之家 的基础上修正、重写的,原来的代码中出现了一些致命错误,在下面的代码中都已修复。另外由于最后一位是校验位,需要计算求得,为了方便使用我将代码改为输入 12 或 13 位均可识别,12 位自动补全,13 位自动覆盖。 原始的代码错误主要有:

  1. 校验位计算错误:当最后一位计算结果为 10 记作 0;
  2. 奇偶排列选择器的数据缺失。
<?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]);
    }
?>