質問
(バーコードスキャナーを使用して)画像からバーコードを検索して読み取ることができる優れたオープンソースライブラリを探しています。スタックオーバーフローに関する他の質問から、 ZXing (" Zebra Crossing")が見つかりました。とてもいいです。 Java用に作られていますが、C#ポートがあります-ただし、完全ではないかもしれません。そのような状況からバーコードを解析するのに十分な信頼性だと思いますか、または他のライブラリの方が優れていると思いますか?
編集:エドがコメントで指摘したように、最初に試してみてください。うわー、私はそれを考えていませんでした。 :)しかし、私の質問は、部分的なポートが十分に信頼できるかどうかだと思います-あなたのいずれかが以前にそれを使用したことがある場合、熟練してスキャンできますか?
解決
これはもちろん、何に使用するかによって異なります。 Javaバージョンのzxingでさえ、いくつかの重要な制限とパフォーマンスの問題があります。たとえば、ページ上で1つのバーコードのみを検索できます。また、ページ上の1-Dバーコードの位置を特定するために使用するアルゴリズムは特に効率的ではありません(2Dバーコードのアルゴリズムについては考えもしません。これは私が取り組んでいたプロジェクトの要件の一部ではありませんでした)。これはすべて対処可能なものです-数か月前に機能強化を開始し、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を介して設定できるものである必要がありますが、プログレッシブストラテジーは、スローできるすべてのケースで古いストラテジーよりも速いことがわかりました(少し速くなるだけではありません-はるかに高速)。
他のヒント
私はJavaバージョンを1年以上使用しており、毎日約100スキャンしており、非常にうまく機能しています。 C#バージョンがこれ以上悪くなる理由はありません。
Javaバージョンを ikvmc でコンパイルして、C#コードからアクセスするよりも。