2009-10-28 14 views
8

Estoy buscando una buena biblioteca de código abierto que pueda encontrar y leer un código de barras de una imagen (en comparación con un escáner de código de barras). De otras preguntas sobre Stack Overflow, descubrí que ZXing ("Paso de cebra") es bastante bueno. Aunque está hecho para Java, hay un puerto C#; sin embargo, creo que podría no estar completo. ¿Cree que es confiable suficiente para analizar un código de barras de una situación como esta, o es alguna otra biblioteca mejor?ZXing ("Paso de cebra") en C#

EDIT: Como señaló Ed en los comentarios, debería intentarlo primero. Wow, no pensé en eso. :) pero supongo que mi pregunta es si el puerto parcial es lo suficientemente confiable: si alguno de ustedes lo ha usado antes, ¿puede escanear con competencia?

+3

¿Por qué no solo, ya sabes ... pruébalo? –

+0

@Ed Oh, um, duh! Jaja, ya sabes, creo que necesito cerrar mi pregunta. Oopsey. –

+0

Bueno, la pregunta en sí será útil para las personas en el futuro, por lo que no creo que sea correcto cerrarla. Además, algunas personas pueden tener ideas que requieren tiempo para aprender, y es posible que las pierda a primera vista. Solo estaba sugiriendo que, mientras tanto, probarlo sería mi primer objetivo. –

Respuesta

2

Esto depende de para lo que lo esté usando, por supuesto. Incluso la versión de zxing de Java tiene algunas limitaciones importantes y problemas de rendimiento. Por ejemplo, solo puede encontrar un código de barras en una página. Además, los algoritmos que utiliza para localizar el código de barras 1-D en la página no son particularmente eficientes (no tiene idea sobre los algoritmos para los códigos de barras 2-D, eso no formaba parte de los requisitos del proyecto en el que estaba trabajando). Esto es todo lo que se puede abordar: comencé una mejora hace unos meses y pude mejorar significativamente el rendimiento y la confiabilidad de la ubicación en 1-D, pero nuestras prioridades de desarrollo han cambiado, así que no he trabajado en eso desde entonces.

En cuanto a si el puerto parcial a C# es bueno, si desea publicar de nuevo con cuáles son las diferencias, me gustaría comentar.

EDITAR - aquí es parte de la refactorización que hice:

En primer lugar, el factor cabo RowNumberStrategy de la siguiente manera:

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

} 



} 

entonces la parte superior de doDecode se convierte en la siguiente:

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

en última instancia, esto debería ser algo que se puede establecer a través de DecodeHintType, pero hemos encontrado que la estrategia progresiva es más rápida que la estrategia anterior en todos los casos que pudimos t hola (y no solo un poco más rápido - mucho más rápido).

+0

Pruebe el MultipleBarcodeReader para encontrar varios códigos de barras en una imagen. No estoy seguro de lo que considera ineficaz sobre la detección 1D: escanea un par de líneas desde el centro hacia afuera. En todo caso, el modo predeterminado es rápido pero rápido. –

+0

Definitivamente revisaré MBR, gracias por la sugerencia. Algorítmicamente, la estrategia de escaneo no funciona eficientemente para imágenes grandes (digamos 3300 filas) porque usa un enfoque de pasos fijos. Volveré a publicar con lo que estoy hablando en una publicación completa para que pueda mostrar el código. –

+0

No, el paso de escaneo es una función de la altura; de manera predeterminada, omite la altura/16 filas de la imagen en cada paso. –

-1

Intente compilar la versión java con ikvmc, luego acceda a ella desde su código C#.

3

He estado usando la versión java durante más de un año, escaneando aproximadamente 100 diarios, y funciona muy bien. No veo ninguna razón por la que la versión de C# sea peor.