7

使用3 of 9条码很容易生成Font()

Font f = new Font("Free 3 of 9", 80);
this.Font = f;

Label l = new Label();
l.Text = "*STACKOVERFLOW*";
l.Size = new System.Drawing.Size(800, 600);
this.Controls.Add(l);

this.Size = new Size(800, 600);

它的工作。我看到了条形码,我可以扫描它。现在我想使用其他东西,比如Code 128为此我需要安装字体(完成)并更改

Font f = new Font("Free 3 of 9", 80);Font f = new Font("Code 128", 80);

之后,我在窗口上看到一个条形码。问题是我无法扫描它。我认为那是因为我没有为条形码使用正确的开始停止标签。据我了解,必须始终有一个开始/停止字符或其他字符。对于 3 of 9 是代码 128 的 *,我不确定。在 wiki 上有Start Code A所以我试过了

Font f = new Font("<Start Code A>test<Stop>", 80);Font f = new Font("<Start Code A>test<Stop Code A>", 80);等等...我无法扫描输出。因为扫描仪找不到开始和停止字符。有任何想法吗?谢谢

4

3 回答 3

4

Code 128 完全可以用字体表示。虽然它比 3 of 9 更棘手,因为您必须在末尾包含一个校验和字符,该校验和字符需要根据条形码的内容动态计算。还有 3 个不同的版本,每个版本都有不同的起始字符。

换句话说,条形码需要像这样布置:

[start char][barcode][checksum][stop char]

code128 的好处是它比 3 of 9 简洁得多。

这个页面帮助我制定了计算校验和的算法。

该算法的一个非常一般的概述是:

  1. 条形码的每个字符都会根据字符是什么以及它在条形码中的位置分配给它一个特定的值。

  2. 将上述 1) 中的所有值相加。

  3. 获取上面 2) 中总和的模数 103 值。

  4. 在大多数情况下,校验和字符将是 ASCII 码:(模数加 32),如上面 3) 中确定的。

有一些细微差别,我最终需要在所有事物的 javascript 中创建这个算法(没有问题)。为了我自己的未来参考并展示一些细微差别,这就是它的样子:

/*
 * This is the variable part of my barcode, I append this to a 
 * static prefix later, but I need to perform logic to compute the 
 * checksum for this variable. There is logic earlier that enforces 
 * this variable as a 9 character string containing only digits.   
 */ 
var formIncrement = // a 9 char "digit" string variable

/*
 * Dynamically compute the total checksum value (before modulus) 
 * for the variable part of my barcode, I will need to get a modulus 
 * from this total when I am done. If you need a variable number of 
 * characters in your barcodes or if they are not all digits 
 * obviously something different would have to be done here.  
 */ 
var incrementCS = ((parseInt(formIncrement.charAt(0)) + 16) * 7) +
                  ((parseInt(formIncrement.charAt(1)) + 16) * 8) +
                  ((parseInt(formIncrement.charAt(2)) + 16) * 9) +
                  ((parseInt(formIncrement.charAt(3)) + 16) * 10) +
                  ((parseInt(formIncrement.charAt(4)) + 16) * 11) +
                  ((parseInt(formIncrement.charAt(5)) + 16) * 12) +
                  ((parseInt(formIncrement.charAt(6)) + 16) * 13) +
                  ((parseInt(formIncrement.charAt(7)) + 16) * 14) + 
                  ((parseInt(formIncrement.charAt(8)) + 16) * 15);

/*
 * 452 is the total checksum for my barcodes static prefix (600001), 
 * so it doesn't need to be computed dynamically, I just add it to 
 * the variable checksum total determined above and then get the 
 * modulus of that sum:  
 */ 
var checksum = (452 + incrementCS) % 103


var barcode = "š600001" + formIncrement

/*
 * The 0 and the 95 - 102 cases had to be defined explicitly because 
 * their checksum figures do not line up with the javascript char 
 * codes for some reason (see the code 128 definition table in the 
 * linked page) otherwise we simply need to get the charCode of the 
 * checksum + 32. I also tack on the stop char here. 
 */ 
switch (checksum) {
    case 0 :
    barcode += "€œ";
    break;
    case 95 :
    barcode += "‘œ";
    break;
    case 96 :
    barcode += "’œ";
    break;
    case 97 :
    barcode += "“œ";
    break;
    case 98 :
    barcode += "”œ";
    break;
    case 99 :
    barcode += "•œ";
    break;
    case 100 :
    barcode += "–œ";
    break;
    case 101 :
    barcode += "—œ";
    break;
    case 102 :
    barcode += "˜œ";
    break;
    default :
    barcode += String.fromCharCode(checksum + 32) + "œ";
}

return barcode;

您可能会注意到我的示例中的开始和停止字符 (š, œ) 似乎与链接页面上显示的不匹配。如果我记得我认为这是因为我有一些非标准的 code128 字体并且这些字符被翻译成正确的字符。

编辑

我检查了我的文档。看起来我从这里得到了字体。使用该字体并使用上面的算法,我刚刚制作了一个 code128b 条形码,test它的štestwœ扫描结果很好。您的校验和算法似乎工作正常,因为我们都有,w但是如果您获得以下信息,您的起始码和停止码似乎已关闭:ÌtestwÎ

我特意寻找我正在使用的相同条形码字体,因为我感觉不同品牌的 code128 字体可能会实现不同的字符来表示开始和停止条形码。

于 2012-06-24T17:47:56.437 回答
1

查看 Barcode128的Wikipedia 页面,我认为您应该根据Bar Code Widths段落和表格使用 ASCII 码 208-210 来分隔一个块。

于 2012-06-11T09:08:39.550 回答
0

规格

维基百科的 Code 128 页面对规范的解释如下:

Code 128 条码有七个部分:

  1. 安静区域
  2. 开始符号
  3. 编码数据
  4. 复选符号(必填)
  5. 停止符号
  6. 最终柱(通常被认为是停止符号的一部分)
  7. 安静区域

校验符号是根据所有符号的加权和(模 103)计算得出的。

数据编码

除了我们需要提供开始和停止符号以及检查符号的数据之外,该字体将处理所需的区域和线条。

校验位计算部分解释了校验和是通过将起始代码“值”与每个符号的“值”乘以其在条形码字符串中的位置的乘积来计算的。然后将乘积之和以 103 为模。由于本例中的起始码值为 103,其中 103 为 0,因此可以忽略它,我们只需对数据符号进行计数即可。

使用免费条形码字体@ dobsonsw,它是 Code 128B 或 Code set B,字体支持 95 个字符,ASCII 字符 32 到 127。要显示校验符号,还有 9 个额外的溢出字符,它们是乱序的,需要占。

正如@egerardus 得出的那样,这种特殊字体使用非标准的开始(353)和停止(339)符号以及不同范围的溢出字符(8216, 8217, 8220, 8221, 8226, 8211, 8212, 0732, 8364)。

执行

以下是条码数据编码的工作 C# 实现。

private string BarcodeEncode(string value)
{
    int[] overChars = { 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8364 };
    char[] valueChars = value.ToCharArray();
    int[] checksumVals = new int[value.Length];

    for (int n = 0; n < valueChars.Length; n++)
    {
        checksumVals[n] = (((byte)valueChars[n]) - 32) * (n + 1);
    }

    int checksum = checksumVals.Sum() % 103;
    char check = (char)(checksum + 33);
    if (checksum > 93)
        check = (char)overChars[checksum - 94];

    string start = ((char)353).ToString();
    string stop = ((char)339).ToString();

    return start + value + check.ToString() + stop;
}

其次是等效的 JavaScript 实现。

function barcodeEncode(value) {
    var overChars = [8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8364];
    var checksum = [...value]
            .map((i, n) => (i.charCodeAt(0) - 32) * ++n)
            .reduce((a, b) => a + b, 0) % 103;
    return String.fromCharCode(353) + value
        + (checksum < 94
            ? String.fromCharCode(checksum + 33)
            : String.fromCharCode(overChars[checksum - 94]))
        + String.fromCharCode(339);
}

开心!

于 2021-06-25T08:52:37.857 回答