示例#1
0
        /**
           * Identify where the end of the middle / payload section ends.
           *
           * @param row row of black/white values to search
           * @return Array, containing index of start of 'end block' and end of 'end
           *         block'
           * @throws ReaderException
           */
        int[] decodeEnd(BitArray row)
        {
            // For convenience, reverse the row and then
            // search from 'the start' for the end block
            row.reverse();

            int endStart = skipWhiteSpace(row);
            int[] endPattern;
            try {
              endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
            } catch (ReaderException e) {
              // Put our row of data back the right way before throwing
              row.reverse();
              throw e;
            }

            // The start & end patterns must be pre/post fixed by a quiet zone. This
            // zone must be at least 10 times the width of a narrow line.
            // ref: http://www.barcode-1.net/i25code.html
            validateQuietZone(row, endPattern[0]);

            // Now recalc the indicies of where the 'endblock' starts & stops to
            // accomodate
            // the reversed nature of the search
            int temp = endPattern[0];
            endPattern[0] = row.getSize() - endPattern[1];
            endPattern[1] = row.getSize() - temp;

            // Put the row back the righ way.
            row.reverse();
            return endPattern;
        }
        /**
           * We're going to examine rows from the middle outward, searching alternately above and below the
           * middle, and farther out each time. rowStep is the number of rows between each successive
           * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
           * middle + rowStep, then middle - (2 * rowStep), etc.
           * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
           * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
           * image if "trying harder".
           *
           * @param image The image to decode
           * @param hints Any hints that were requested
           * @return The contents of the decoded barcode
           * @throws ReaderException Any spontaneous errors which occur
           */
        private Result doDecode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
        {
            int width = image.getWidth();
            int height = image.getHeight();
            BitArray row = new BitArray(width);

            int middle = height >> 1;
            bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
            int rowStep = Math.Max(1, height >> (tryHarder ? 7 : 4));
            int MaxLines;
            if (tryHarder) {
              MaxLines = height; // 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
            }

            for (int x = 0; x < MaxLines; x++) {

              // Scanning from the middle out. Determine which row we're looking at next:
              int rowStepsAboveOrBelow = (x + 1) >> 1;
              bool isAbove = (x & 0x01) == 0; // i.e. is x even?
              int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
              if (rowNumber < 0 || rowNumber >= height) {
                // Oops, if we run off the top or bottom, stop
                break;
              }

              // Estimate black point for this row and load it:
              try {
                image.estimateBlackPoint(BlackPointEstimationMethod.ROW_SAMPLING, rowNumber);
              } catch (ReaderException re) {
                continue;
              }

              image.getBlackRow(rowNumber, row,0, width);

              // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
              // handle decoding upside down barcodes.
              for (int attempt = 0; attempt < 2; attempt++) {
                if (attempt == 1) { // trying again?
                  row.reverse(); // reverse the row and continue
                }
                try {
                  // Look for a barcode
                  Result result = decodeRow(rowNumber, row, hints);
                  // We found our barcode
                  if (attempt == 1) {
                    // But it was upside down, so note that
                    result.putMetadata(ResultMetadataType.ORIENTATION, 180);
                    // And remember to flip the result points horizontally.
                    ResultPoint[] points = result.getResultPoints();
                    points[0] = (ResultPoint) new GenericResultPoint(width - points[0].getX() - 1, points[0].getY());
                    points[1] = (ResultPoint)new GenericResultPoint(width - points[1].getX() - 1, points[1].getY());
                  }
                  return result;
                } catch (ReaderException re) {
                  // continue -- just couldn't decode this row
                }
              }
            }

            throw new ReaderException();
        }