Domanda

Sto cercando una buona libreria open source in grado di trovare e leggere un codice a barre da un'immagine (anziché utilizzare uno scanner di codici a barre). Da altre domande su Stack Overflow, ho scoperto che ZXing (" Zebra Crossing ") è abbastanza buono. Sebbene sia realizzato per Java, esiste una porta C #, tuttavia, credo che potrebbe non essere completo. Pensi che sia affidabile abbastanza per analizzare un codice a barre da una situazione del genere, o qualche altra libreria è migliore?

EDIT: Come ha sottolineato Ed nei commenti, dovrei provarlo prima. Caspita, non ci ho pensato. :) ma immagino che la mia domanda sia se la porta parziale sia abbastanza affidabile - se qualcuno di voi l'ha già usata prima, può scansionare con competenza?

È stato utile?

Soluzione

Dipende da cosa lo stai usando, ovviamente. Anche la versione Java di zxing presenta alcune importanti limitazioni e problemi di prestazioni. Ad esempio, può trovare un solo codice a barre su una pagina. Inoltre, gli algoritmi che utilizza per localizzare il codice a barre 1-D sulla pagina non sono particolarmente efficienti (nessuna idea sugli algoritmi per i codici a barre 2-D - che non faceva parte dei requisiti del progetto su cui stavo lavorando). Questo è tutto ciò che può essere affrontato: ho iniziato un miglioramento qualche mese fa e sono stato in grado di migliorare in modo significativo le prestazioni e l'affidabilità della posizione 1-D, ma le nostre priorità di sviluppo sono cambiate, quindi da allora non ci ho più lavorato.

Per sapere se la porta parziale su C # è buona, se vuoi postare indietro con quali sono le differenze, sarei felice di commentare.

EDIT: ecco alcuni dei refactoring che ho fatto:

Innanzitutto, estrai RowNumberStrategy come segue:

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

}



}

quindi la parte superiore di doDecode diventa la seguente:

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){
...
}

alla fine, questo dovrebbe essere qualcosa che può essere impostato tramite un DecodeHintType, ma abbiamo scoperto che la strategia progressiva è più veloce della vecchia strategia in ogni caso che potremmo lanciarci (e non solo un po 'più veloce - molto più veloce).

Altri suggerimenti

Uso la versione java da più di un anno, eseguendo la scansione di circa 100 ogni giorno e funziona alla grande. Non vedo alcun motivo per cui la versione c # sarebbe peggiore.

Prova a compilare la versione java con ikvmc , poi accedi ad esso dal tuo codice C # .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top