ZXing ("переход зебры") в C#



Я ищу хорошую библиотеку с открытым исходным кодом, которая может найти и прочитать штрих-код с изображения (в отличие от использования сканера штрих-кодов). Из других вопросов о переполнении стека я обнаружил, что ZXing ("переход зебры") довольно хорош. Хотя он сделан для Java, есть порт C#, однако я считаю, что он может быть неполным. Как вы думаете, достаточно ли это надежно , чтобы разобрать штрих-код из такой ситуации, или лучше какая-то другая библиотека?



EDIT: Как Ed как указано в комментариях, я должен просто попробовать его первым. Ничего себе, я об этом не подумал. :) но я думаю, что мой вопрос заключается в том, достаточно ли надежен частичный порт - если кто-то из вас использовал его раньше, может ли он сканировать с мастерством?

520   3  

3 ответов:

Это, конечно, зависит от того, для чего вы его используете. Даже Java-версия zxing имеет некоторые важные ограничения и проблемы с производительностью. Например, он может найти только один штрих-код на странице. Кроме того, алгоритмы, которые он использует для размещения 1-D штрих-кодов на странице, не особенно эффективны (нет представления об алгоритмах для 2 - D штрих-кодов-это не входило в требования к проекту, над которым я работал). Это все вещи, которые можно решить - я начал улучшение несколько несколько месяцев назад и смог значительно улучшить производительность и надежность 1-D location, но наши приоритеты в разработке изменились, поэтому с тех пор я не работал над этим.

Что касается того, хорош ли частичный порт для C#, если вы хотите отправить ответ с тем, в чем заключаются различия, я буду рад прокомментировать.

EDIT-вот некоторые из рефакторинга, которые я сделал:

Во-первых, разложите 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 уже больше года, сканирую около 100 раз в день, и она отлично работает. Я не вижу причин, по которым версия c# была бы хуже.

Попробуйте скомпилировать версию java с помощью ikvmc, чем получить доступ к ней из вашего кода C#.

Comments

    Ничего не найдено.