PHP生成条形码



<?php

//请输入12位条形码或7位条形码(条形码最后一位位自动补全);
$num = '693515791059';

//判断条形码长度
if (strlen($num) == 12) {
    EAN_13($num);
} else if (strlen($num) == 7) {
    EAN_8($num);
} else {
    die("必须是12位数或者7位数");
}

/**
 * 生成EAN_13条形码
 * @param type $code
 */
function EAN_13($code) {
    //一个单元的宽度
    $lw = 2;
    //条码高 
    $hi = 100;
    //EAN_13条形码的二进制换算(大概是这样,不是特别确定)
    $Guide = array(1 => 'AAAAAA', 'AABABB', 'AABBAB', 'ABAABB', 'ABBAAB', 'ABBBAA', 'ABABAB', 'ABABBA', 'ABBABA');
    $Lstart = '101';
    $Lencode = array("A" => array('0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011'),
        "B" => array('0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111'));
    $Rencode = array('1110010', '1100110', '1101100', '1000010', '1011100',
        '1001110', '1010000', '1000100', '1001000', '1110100');

    $center = '01010';

    $ends = '101';

    //计算条形码最后一位计算参数
    $lsum = 0;
    $rsum = 0;
    //计算条形码最后一位计算方法
    for ($i = 0; $i < strlen($code); $i++) {
        //如果$i是奇数
        if ($i % 2) {
            // $lsum等于¥code的偶数位相加
            $lsum +=(int) $code[$i];
        } else {
            // $rsum等于¥code的奇数位相加
            $rsum +=(int) $code[$i];
        }
    }
    //计算参数
    $tsum = $lsum * 3 + $rsum;
    //计算条形码最后一位
    $code[12] = (10 - ($tsum % 10));

    //条形码数值转为二进制(大概是这样,不是特别确定)
    $barcode = $Lstart;
    for ($i = 1; $i <= 6; $i++) {
        $barcode .= $Lencode [$Guide[$code[0]][($i - 1)]] [$code[$i]];
    }
    $barcode .= $center;

    for ($i = 7; $i < 13; $i++) {
        $barcode .= $Rencode[$code[($i)]];
    }
    $barcode .= $ends;

    //绘制一个空白图像
    $img = ImageCreate($lw * 95 + 60, $hi + 30);
    //绘制方法为白色
    $fg = ImageColorAllocate($img, 0, 0, 0);
    //绘制方法为黑色
    $bg = ImageColorAllocate($img, 255, 255, 255);
    //绘制空白图像为黑色
    ImageFilledRectangle($img, 0, 0, $lw * 95 + 60, $hi + 30, $bg);

    //绘制条形码
    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 * $lw) + 30, 5, ($x + 1) * $lw + 29, $hi + 5 + $sh, $color);
    }

    //绘制条形码下方数字第1位
    ImageString($img, 5, 20, $hi + 5, $code[0], $fg);
    //绘制条形码下方数字其余12位
    for ($x = 0; $x < 6; $x++) {
        //绘制2到7位数字
        ImageString($img, 5, $lw * (8 + $x * 6) + 30, $hi + 5, $code[$x + 1], $fg);
        //绘制7到13位数字
        ImageString($img, 5, $lw * (53 + $x * 6) + 30, $hi + 5, $code[$x + 7], $fg);
    }
    //设置图像格式
    header("Content-Type: image/png");
    // 定义储存文件位置
    $file_name = dirname(__FILE__) . '/../../assets/templates/EAN_13.png';
    //储存条形码
    ImagePNG($img, $file_name);
    //显示条形码
    ImagePNG($img);
}

/**
 * 生成EAN_8条形码
 * @param type $code
 */
function EAN_8($code) {


    $s = $code;
    //条形码宽度
    $width = 2;
    //条形码高度
    $height = 80;
    //判断不允许字符
    if (preg_match("/^\d{7}/", $s) == 0) {
        exit('存在不允许的字符!');
    }

    //条形码第8位的计算参数
    $sum_even = 0;
    $sum_odd = 0;

    for ($i = 0; $i < 7; ++$i) {
        if ($i % 2 == 0) {
            $sum_odd+=(int) $s{$i};
        } else {
            $sum_even+=(int) $s{$i};
        }
    }
    //计算出条形码的第8位
    $checkcode = (10 - ($sum_odd * 3 + $sum_even) % 10) % 10;
    $s.=$checkcode;

    $result = '0000000101'; //前空白7位+起始码3位

    for ($i = 0; $i < 4; ++$i) {
        $result.=ean8($s{$i}, 'A');
    }

    $result.='01010'; //中间码5位

    for ($i = 4; $i < 8; ++$i) {
        $result.=ean8($s{$i}, 'C');
    }

    $result.='1010000000'; //终止码3位+后空白7位
    //绘制一个空白图像
    $img = imagecreatetruecolor($width * 81, $height + $width * 8);
    //绘制方法为白色
    $black = imagecolorallocate($img, 0, 0, 0);
    //绘制方法为黑色
    $white = imagecolorallocate($img, 255, 255, 255);
    //绘制空白图像为黑色
    imagefill($img, 0, 0, $white);
    //一个条码单元宽度
    imagesetthickness($img, $width);
    //绘制条形码
    for ($i = 0; $i < 81; ++$i) {
        //判断使用什么颜色
        $color = $result{$i} == 1 ? $black : $white;
        //中间码的条码长度
        $h = $height - 1;
        if ($i < 10 || ($i >= 38 && $i < 43) || $i >= 71) {
            //延长起始码和中间码的条码长度
            $h+=$width * 4;
        }
        //输出左资料码数字
        if ($i >= 10 && $i < 38 && ($i - 10) % 7 == 0) {
            imagechar($img, 4, $i * $width + 2, $height + $width, $s{($i - 10) / 7}, $black);
        }
        //输出右资料码数字
        if ($i >= 43 && $i < 71 && ($i - 43) % 7 == 0) {
            imagechar($img, 4, $i * $width, $height + $width, $s{($i - 43) / 7 + 4}, $black);
        }
        //绘制条码
        imageline($img, $i * $width, 0, $i * $width, $h, $color);
    }
    //设置图片格式
    header("Content-type: image/png");
    //设置图片储存位置以及名称
    $file_name = dirname(__FILE__) . '/../../assets/templates/EAN_8.png';
    //储存图片
    ImagePNG($img, $file_name);
    //显示图片
    ImagePNG($img);
}

/**
 * EAN_8条形码的二进制换算(大概是这样,不是特别确定)
 * @param type $c
 * @param type $type
 * @return string
 */
function ean8($c, $type) {
    switch ($type) {
        case 'A': {
                switch ($c) {
                    case '0': return "0001101";
                    case '1': return "0011001";
                    case '2': return "0010011";
                    case '3': return "0111101";
                    case '4': return "0100011";
                    case '5': return "0110001";
                    case '6': return "0101111";
                    case '7': return "0111011";
                    case '8': return "0110111";
                    case '9': return "0001011";
                    default: return "Error!";
                }
            }
        case 'C': {
                switch ($c) {
                    case '0': return "1110010";
                    case '1': return "1100110";
                    case '2': return "1101100";
                    case '3': return "1000010";
                    case '4': return "1011100";
                    case '5': return "1001110";
                    case '6': return "1010000";
                    case '7': return "1000100";
                    case '8': return "1001000";
                    case '9': return "1110100";
                    default: return "Error!";
                }
            }
        default: return "Error!";
    }
}
?>


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值