8

画像からバーコードを見つけて読み取ることができる(バーコードスキャナーを使用するのではなく)優れたオープンソースライブラリを探しています。Stack Overflowに関する他の質問から、ZXing( "Zebra Crossing")が非常に優れていることがわかりました。Java用に作られていますが、C#ポートがありますが、完全ではないかもしれません。そのような状況からバーコードを解析するのに十分な信頼性があると思いますか、それとも他のライブラリの方が優れていると思いますか?

編集:エドがコメントで指摘したように、私は最初にそれを試してみるべきです。うわー、私はそれを考えていませんでした。:)しかし、私の質問は、部分ポートが十分に信頼できるかどうかだと思います-もしあなたの誰かが以前にそれを使用したことがあるなら、それは熟練してスキャンできますか?

4

3 に答える 3

3

私は Java バージョンを 1 年以上使用しており、毎日約 100 件をスキャンしていますが、うまく機能しています。C# バージョンがこれ以上悪くなる理由はわかりません。

于 2009-10-29T02:45:09.623 に答える
2

もちろん、これは使用目的によって異なります。zxing の Java バージョンでさえ、いくつかの重要な制限とパフォーマンスの問題があります。たとえば、1 ページで検出できるバーコードは 1 つだけです。また、ページ上の 1 次元バーコードを見つけるために使用するアルゴリズムは、特に効率的ではありません (2 次元バーコードのアルゴリズムについてはわかりません。これは、私が取り組んでいたプロジェクトの要件の一部ではありませんでした)。これは対処できるすべてのものです.数か月前に機能強化を開始し、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 を介して設定できるものである必要がありますが、プログレッシブ戦略は、スローできるすべてのケースで古い戦略よりも高速であることがわかりました (少しだけ高速ではなく、はるかに高速です)。

于 2009-10-29T03:47:35.067 に答える
-1

C# コードからアクセスするよりも、 ikvmcを使用して Java バージョンをコンパイルしてみてください。

于 2009-10-29T00:40:29.197 に答える