【问题标题】:Something wrong with barcode (Code 128) font not scanning条码(代码 128)字体出现问题,无法扫描
【发布时间】:2012-06-14 04:17:35
【问题描述】:

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

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);

之后,我在窗口上看到了一个条形码。问题是我无法扫描那个。我认为那是因为我没有为条形码使用正确的 startstop 标签。据我了解,必须始终有一个开始/停止字符或其他字符。对于 9 个中的 3 个,我不确定 Code 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); 等等...我无法扫描输出。因为扫描仪找不到开始和停止字符。有任何想法吗?谢谢

【问题讨论】:

  • 您是否创建了正确的校验和字符?查看this page 以了解如何计算校验和 对于另一种选择,请查看以下链接 - 这允许您创建条形码位图:codeproject.com/KB/graphics/…
  • 我发现您的条形码有问题,请参阅答案底部的编辑。

标签: c# .net barcode


【解决方案1】:

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

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

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

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

This page 帮助我制定了计算校验和的算法。

算法的一个非常概括的概述是:

  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 字体,而这些字符被翻译成正确的。

编辑

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

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

【讨论】:

  • 这很有趣,谢谢。如果我从页面下载源代码并启动它,我能够生成代码 128(或看起来像代码 128 的东西)但我无法扫描它。嗯,有问题。
  • @sabisabi 如果您发布您的条形码包含的字符,我可能会告诉您它有什么问题。
  • 嗨,我的输入值是“test”,我的编码值是“ÌtestwΔ - 我得到一个条形码,但我无法扫描它(jtbarton.com/Barcodes/BarcodeStringBuilderExample.aspx
  • 现在不知何故工作。我试图删除所有其他条形码字体并安装唯一的一个代码 128 - 我仍然没有 100% 得到它,但它可以工作;)很高兴知道,正如我们看到很多人(甚至是“帮助者”)都在想这不能与标准字体一起使用,但可以。谢谢。
  • 我可以正确生成条形码并读取它,但是当校验和为 32 时,指示的字体无法显示字符(如 100004392)。并且找不到可以显示此 32 AND 前缀/后缀的字体。有什么想法吗?
【解决方案2】:

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

【讨论】:

  • 那是我不明白的。 208到210应该是开始“标签”吧?停止标签是211?然后我在我的字符串的开头添加一个 208 之类的 ascii 字符,最后添加一个 ascii char 211 - 不知道如何使用 c#
  • 像这样。 (char)(0208)).ToString() 。如果你一次转换几个字节,有不同的方法,但对于这个应该足够了。 stackoverflow.com/questions/13736480/… 或只是 google 用于将 char 字节数组转换为字符串。
【解决方案3】:

规格

Wikipedia's Code 128 page对规范的解释如下:

Code 128 条码有七个部分:

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

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

数据编码

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

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

使用Free barcode fonts @ 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);
}

开心!

【讨论】:

    猜你喜欢
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    相关资源
    最近更新 更多