2009-10-28 80 views
8

我正在寻找一个很好的开源库,可以从图像中找到并读取条形码(与使用条形码扫描器相比)。从堆栈溢出的其他问题,我发现ZXing(“斑马线”)是相当不错的。尽管它是为Java编写的,但有一个C#端口 - 但是,我认为它可能不完整。你认为这是可靠的足以从这样的情况解析条码,或者是其他一些图书馆更好?C中的ZXing(“Zebra Crossing”)#

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

+3

为什么你不只是,你知道...尝试一下吗? – 2009-10-28 23:39:19

+0

@Ed哦,恩,呃!哈哈,你知道,我想我需要结束我的问题。 Oopsey。 – 2009-10-28 23:40:48

+0

嗯,这个问题本身对将来的人会有用,所以我认为这是不对的。另外,有些人可能会有需要花时间学习的见解,乍一看你可能会错过。我只是在暗示,同时,尝试这将是我的第一个目标。 – 2009-10-28 23:51:58

回答

2

当然,这取决于您使用的是什么。即使Java版本的zxing也有一些重要的限制和性能问题。例如,它只能在页面上找到一个条形码。此外,它用于在页面上定位1-D条形码的算法效率不高(不了解二维条形码的算法 - 这不属于我正在开发的项目的要求)。这就是所有可以解决的问题 - 几个月前我开始进行增强,并且能够显着提高一维位置性能和可靠性,但是我们的开发优先级已经发生变化,因此我从那时起就没有开发过它。至于是否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设置的东西,但我们发现在任何情况下,渐进式策略都比旧式策略要快耸耸肩(而不仅仅是更快一点 - 更快)。

+0

尝试使用MultipleBarcodeReader在图像中查找多个条形码。不知道你发现一维检测效率低下 - 从中​​心向外扫描几条线。如果有的话,默认模式是快速但粗略的。 – 2009-11-01 01:39:59

+0

我肯定会检查MBR - 感谢您的提示。在算法上,扫描策略对于大图像(比如说3300行)无效,因为它使用了固定步进方法。我会在全文中回复我正在谈论的内容,以便我可以展示代码。 – 2009-11-05 05:30:35

+0

不,扫描步骤是高度的函数 - 默认情况下,它跳过每一步中图像的高度/ 16行。 – 2009-11-17 11:49:39

-1

尝试编译与ikvmc的Java版本,而不是从您的C#代码访问它。

3

我一直在使用Java版本超过一年,每天扫描大约100次,而且效果很好。我看不出有任何理由的C#版本会更糟糕。