8

我正在寻找一个很好的开源库,它可以从图像中查找和读取条形码(而不是使用条形码扫描仪)。从 Stack Overflow 上的其他问题中,我发现ZXing(“斑马线”)相当不错。虽然它是为 Java 制作的,但有一个 C# 端口 - 但是,我相信它可能不完整。您认为从这种情况下解析条形码是否足够可靠,还是其他库更好?

编辑:正如 Ed 在评论中指出的那样,我应该先尝试一下。哇,我没想到。:) 但我想我的问题是部分端口是否足够可靠 - 如果你们以前使用过它,它可以熟练地扫描吗?

4

3 回答 3

3

我已经使用java版本一年多了,每天扫描大约100个,效果很好。我认为没有理由 C# 版本会更糟。

于 2009-10-29T02:45:09.623 回答
2

当然,这取决于您使用它的目的。即使是 zxing 的 Java 版本也有一些重要的限制和性能问题。例如,它只能在一个页面上找到一个条形码。此外,它用于在页面上定位一维条码的算法并不是特别有效(不知道二维条码的算法——这不是我正在从事的项目的要求的一部分)。这些都是可以解决的问题——几个月前我开始进行增强,并且能够显着提高一维定位性能和可靠性,但是我们的开发重点已经转移,所以从那以后我就没有继续努力了。

至于 C# 的部分移植是否良好,如果您想回帖说明有什么区别,我很乐意发表评论。

编辑 - 这是我所做的一些重构:

首先,将 RowNumberStrategy 分解如下:

public interface RowNumberStrategy {
public int getNextRowNumber();

public class OriginalRowStrategy implements RowNumberStrategy{
    int middle;
    boolean tryHarder = false;
    int rowStep;
    int maxLines;
    int maxRows;

    int x;

    public OriginalRowStrategy(int maxRows, boolean tryHarder) {
        this.x = 0;
        this.maxRows = maxRows;
        this.middle = maxRows >> 1; // divide by 2
        this.tryHarder = tryHarder;
        rowStep = Math.max(1, maxRows >> (tryHarder ? 7 : 4));
        if (tryHarder) {
          maxLines = maxRows; // Look at the whole image, not just the center
        } else {
          maxLines = 9; // Nine rows spaced 1/16 apart is roughly the middle half of the image
        }
    }

    public int getNextRowNumber() {
        if (x > maxLines)
            return -1;

        int rowStepsAboveOrBelow = (x + 1) >> 1;
        boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
        int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
        if (rowNumber < 0 || rowNumber >= maxRows) {
          // Oops, if we run off the top or bottom, stop
          return -1;
        }

        x = x + 1;

        return rowNumber;
    }

}

public class LinearScanRowStrategy implements RowNumberStrategy{
    private final int maxRows;
    private int currentRow;
    public LinearScanRowStrategy(int totalRows) {
        maxRows = totalRows;
        currentRow = 0;
    }

    public int getNextRowNumber() {
        if (currentRow > maxRows)
            return -1;

        return maxRows - 1 - currentRow++;
    }

}

public class ProgressiveScanRowStrategy implements RowNumberStrategy{
    private final int maxRows;
    private int currentStepSize;
    private int currentStep;

    public ProgressiveScanRowStrategy(int totalRows) {
        maxRows = totalRows;
        currentStep = 0;
        currentStepSize = maxRows;
    }

    public int getNextRowNumber() {
        int nextRow = (currentStep++) * currentStepSize;
        if (nextRow < maxRows)
            return nextRow;

        currentStepSize = currentStepSize >> 1;
        if (currentStepSize <= 0)
            return -1;
        currentStep = 1;

        nextRow = currentStep * currentStepSize;

        return nextRow;
    }

}



}

那么 doDecode 的顶部变成如下:

private Result doDecode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {


int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
RowNumberStrategy rowProvider = new RowNumberStrategy.ProgressiveScanRowStrategy(height);  

int rowNumber;
while ((rowNumber = rowProvider.getNextRowNumber()) != -1){
...
}

最终,这应该是可以通过 DecodeHintType 设置的东西,但是我们发现在我们可以抛出的每种情况下,渐进策略都比旧策略更快(而且不仅仅是快一点 -快得多)。

于 2009-10-29T03:47:35.067 回答
-1

尝试使用ikvmc编译 java 版本,而不是从 C# 代码中访问它。

于 2009-10-29T00:40:29.197 回答