Example #1
0
        public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
        {
            DecoderResult decoderResult;

            ResultPoint[] points;
            if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE))
            {
                BitMatrix bits = extractPureBits(image);
                decoderResult = decoder.decode(bits);
                points        = NO_POINTS;
            }
            else
            {
                DetectorResult detectorResult = new Detector(image).detect();
                decoderResult = decoder.decode(detectorResult.getBits());
                points        = detectorResult.getPoints();
            }
            Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATAMATRIX);

            if (decoderResult.getByteSegments() != null)
            {
                result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
            }
            return(result);
        }
Example #2
0
 public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
 {
     try {
         return(doDecode(image, hints));
     } catch (ReaderException re) {
         bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
         if (tryHarder && image.isRotateSupported())
         {
             MonochromeBitmapSource rotatedImage = image.rotateCounterClockwise();
             Result result = doDecode(rotatedImage, hints);
             // Record that we found it rotated 90 degrees CCW / 270 degrees CW
             System.Collections.Hashtable metadata = result.getResultMetadata();
             int orientation = 270;
             if (metadata != null && metadata.ContainsKey(ResultMetadataType.ORIENTATION))
             {
                 // But if we found it reversed in doDecode(), add in that result here:
                 orientation = (orientation + ((int)metadata[ResultMetadataType.ORIENTATION])) % 360;
             }
             result.putMetadata(ResultMetadataType.ORIENTATION, orientation);
             return(result);
         }
         else
         {
             throw re;
         }
     }
 }
 /**
  * Decode an image using the hints provided. Does not honor existing state.
  *
  * @param image The pixel data to decode
  * @param hints The hints to use, clearing the previous state.
  * @return The contents of the image
  * @throws ReaderException Any errors which occurred
  */
 public Result decode(MonochromeBitmapSource image, Hashtable hints){
     try{
        setHints(hints);
        return decodeInternal(image);
     }catch(Exception e){
       throw new ReaderException (e.Message);
     }           
 }
Example #4
0
 /**
  * Locates and decodes a QR code in an image.
  *
  * @return a String representing the content encoded by the QR code
  * @throws ReaderException if a QR code cannot be found, or cannot be decoded
  */
 public Result decode(MonochromeBitmapSource image)
 {
     try{
         return(decode(image, null));
     }
     catch (Exception e) {
         throw new ReaderException(e.Message);
     }
 }
 /**
    * Locates and decodes a QR code in an image.
    *
    * @return a String representing the content encoded by the QR code
    * @throws ReaderException if a QR code cannot be found, or cannot be decoded
    */
 public Result decode(MonochromeBitmapSource image)
 {
     try{
         return decode(image, null);
       }
       catch(Exception e){
         throw new ReaderException(e.Message);
       }
 }
Example #6
0
 /**
  * Decode an image using the hints provided. Does not honor existing state.
  *
  * @param image The pixel data to decode
  * @param hints The hints to use, clearing the previous state.
  * @return The contents of the image
  * @throws ReaderException Any errors which occurred
  */
 public Result decode(MonochromeBitmapSource image, Hashtable hints)
 {
     try{
         setHints(hints);
         return(decodeInternal(image));
     }catch (Exception e) {
         throw new ReaderException(e.Message);
     }
 }
 /**
  * Decode an image using the state set up by calling setHints() previously. Continuous scan
  * clients will get a <b>large</b> speed increase by using this instead of decode().
  *
  * @param image The pixel data to decode
  * @return The contents of the image
  * @throws ReaderException Any errors which occurred
  */
 public Result decodeWithState(MonochromeBitmapSource image){
     try{
       // Make sure to set up the default state so we don't crash
       if (readers == null) {
         setHints(null);
       }
       return decodeInternal(image);
     }catch(Exception e){
       throw new ReaderException(e.Message);
     }            
 }
Example #8
0
 /**
  * Decode an image using the state set up by calling setHints() previously. Continuous scan
  * clients will get a <b>large</b> speed increase by using this instead of decode().
  *
  * @param image The pixel data to decode
  * @return The contents of the image
  * @throws ReaderException Any errors which occurred
  */
 public Result decodeWithState(MonochromeBitmapSource image)
 {
     try{
         // Make sure to set up the default state so we don't crash
         if (readers == null)
         {
             setHints(null);
         }
         return(decodeInternal(image));
     }catch (Exception e) {
         throw new ReaderException(e.Message);
     }
 }
Example #9
0
        private static BitMatrix sampleGrid(MonochromeBitmapSource image,
                                            ResultPoint topLeft,
                                            ResultPoint topRight,
                                            ResultPoint bottomLeft,
                                            ResultPoint alignmentPattern,
                                            int dimension)
        {
            float dimMinusThree = (float)dimension - 3.5f;
            float bottomRightX;
            float bottomRightY;
            float sourceBottomRightX;
            float sourceBottomRightY;

            if (alignmentPattern != null)
            {
                bottomRightX       = alignmentPattern.getX();
                bottomRightY       = alignmentPattern.getY();
                sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
            }
            else
            {
                // Don't have an alignment pattern, just make up the bottom-right point
                bottomRightX       = (topRight.getX() - topLeft.getX()) + bottomLeft.getX();
                bottomRightY       = (topRight.getY() - topLeft.getY()) + bottomLeft.getY();
                sourceBottomRightX = sourceBottomRightY = dimMinusThree;
            }

            GridSampler sampler = GridSampler.Instance;

            return(sampler.sampleGrid(
                       image,
                       dimension,
                       3.5f,
                       3.5f,
                       dimMinusThree,
                       3.5f,
                       sourceBottomRightX,
                       sourceBottomRightY,
                       3.5f,
                       dimMinusThree,
                       topLeft.getX(),
                       topLeft.getY(),
                       topRight.getX(),
                       topRight.getY(),
                       bottomRightX,
                       bottomRightY,
                       bottomLeft.getX(),
                       bottomLeft.getY()));
        }
 /**
  * <p>Creates a finder that will look in a portion of the whole image.</p>
  *
  * @param image image to search
  * @param startX left column from which to start searching
  * @param startY top row from which to start searching
  * @param width width of region to search
  * @param height height of region to search
  * @param moduleSize estimated module size so far
  */
 public AlignmentPatternFinder(MonochromeBitmapSource image,
                        int startX,
                        int startY,
                        int width,
                        int height,
                        float moduleSize) {
   this.image = image;
   this.possibleCenters = new System.Collections.ArrayList(5);
   this.startX = startX;
   this.startY = startY;
   this.width = width;
   this.height = height;
   this.moduleSize = moduleSize;
   this.crossCheckStateCount = new int[3];
 }
Example #11
0
 /**
  * <p>Creates a finder that will look in a portion of the whole image.</p>
  *
  * @param image image to search
  * @param startX left column from which to start searching
  * @param startY top row from which to start searching
  * @param width width of region to search
  * @param height height of region to search
  * @param moduleSize estimated module size so far
  */
 public AlignmentPatternFinder(MonochromeBitmapSource image,
                               int startX,
                               int startY,
                               int width,
                               int height,
                               float moduleSize)
 {
     this.image                = image;
     this.possibleCenters      = new System.Collections.ArrayList(5);
     this.startX               = startX;
     this.startY               = startY;
     this.width                = width;
     this.height               = height;
     this.moduleSize           = moduleSize;
     this.crossCheckStateCount = new int[3];
 }
 public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
 {
     DecoderResult decoderResult;
     ResultPoint[] points;
     if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE)) {
       BitMatrix bits = extractPureBits(image);
       decoderResult = decoder.decode(bits);
       points = NO_POINTS;
     } else {
       DetectorResult detectorResult = new Detector(image).detect();
       decoderResult = decoder.decode(detectorResult.getBits());
       points = detectorResult.getPoints();
     }
     Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATAMATRIX);
     if (decoderResult.getByteSegments() != null) {
       result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
     }
     return result;
 }
Example #13
0
        private Result decodeInternal(MonochromeBitmapSource image)
        {
            try
            {
                int size = readers.Count;
                for (int i = 0; i < size; i++)
                {
                    Reader reader = (Reader)readers[i];
                    try
                    {
                        return(reader.decode(image, hints));
                    }
                    catch (ReaderException re)
                    {
                        // continue
                    }
                }

                throw new ReaderException("");
            }
            catch (Exception e) {
                throw new ReaderException(e.Message);
            }
        }
Example #14
0
        private static BitMatrix sampleGrid(MonochromeBitmapSource image,
                                            ResultPoint topLeft,
                                            ResultPoint bottomLeft,
                                            ResultPoint bottomRight,
                                            int dimension)
        {
            // We make up the top right point for now, based on the others.
            // TODO: we actually found a fourth corner above and figured out which of two modules
            // it was the corner of. We could use that here and adjust for perspective distortion.
            float topRightX = (bottomRight.getX() - bottomLeft.getX()) + topLeft.getX();
            float topRightY = (bottomRight.getY() - bottomLeft.getY()) + topLeft.getY();

            // Note that unlike in the QR Code sampler, we didn't find the center of modules, but the
            // very corners. So there is no 0.5f here; 0.0f is right.
            GridSampler sampler = GridSampler.Instance;

            return(sampler.sampleGrid(
                       image,
                       dimension,
                       0.0f,
                       0.0f,
                       dimension,
                       0.0f,
                       dimension,
                       dimension,
                       0.0f,
                       dimension,
                       topLeft.getX(),
                       topLeft.getY(),
                       topRightX,
                       topRightY,
                       bottomRight.getX(),
                       bottomRight.getY(),
                       bottomLeft.getX(),
                       bottomLeft.getY()));
        }
Example #15
0
 public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
 {
     return maybeReturnResult(ean13Reader.decode(image, hints));
 }
Example #16
0
 public Result decode(MonochromeBitmapSource image)
 {
     return maybeReturnResult(ean13Reader.decode(image));
 }
Example #17
0
        /**
         * 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();
        }
Example #18
0
 /**
  * <p>Creates a finder that will search the image for three finder patterns.</p>
  *
  * @param image image to search
  */
 public FinderPatternFinder(MonochromeBitmapSource image)
 {
     this.image                = image;
     this.possibleCenters      = new System.Collections.ArrayList();
     this.crossCheckStateCount = new int[5];
 }
Example #19
0
 public Result decode(MonochromeBitmapSource image)
 {
     return(decode(image, null));
 }
Example #20
0
        /**
         * This method detects a Data Matrix code in a "pure" image -- that is, pure monochrome image
         * which contains only an unrotated, unskewed, image of a Data Matrix code, with some white border
         * around it. This is a specialized method that works exceptionally fast in this special
         * case.
         */
        private static BitMatrix extractPureBits(MonochromeBitmapSource image)
        {
            // Now need to determine module size in pixels

            int height       = image.getHeight();
            int width        = image.getWidth();
            int minDimension = Math.Min(height, width);

            // First, skip white border by tracking diagonally from the top left down and to the right:
            int borderWidth = 0;

            while (borderWidth < minDimension && !image.isBlack(borderWidth, borderWidth))
            {
                borderWidth++;
            }
            if (borderWidth == minDimension)
            {
                throw new ReaderException();
            }

            // And then keep tracking across the top-left black module to determine module size
            int moduleEnd = borderWidth + 1;

            while (moduleEnd < width && image.isBlack(moduleEnd, borderWidth))
            {
                moduleEnd++;
            }
            if (moduleEnd == width)
            {
                throw new ReaderException();
            }

            int moduleSize = moduleEnd - borderWidth;

            // And now find where the bottommost black module on the first column ends
            int columnEndOfSymbol = height - 1;

            while (columnEndOfSymbol >= 0 && !image.isBlack(borderWidth, columnEndOfSymbol))
            {
                columnEndOfSymbol--;
            }
            if (columnEndOfSymbol < 0)
            {
                throw new ReaderException();
            }
            columnEndOfSymbol++;

            // Make sure width of barcode is a multiple of module size
            if ((columnEndOfSymbol - borderWidth) % moduleSize != 0)
            {
                throw new ReaderException();
            }
            int dimension = (columnEndOfSymbol - borderWidth) / moduleSize;

            // Push in the "border" by half the module width so that we start
            // sampling in the middle of the module. Just in case the image is a
            // little off, this will help recover.
            borderWidth += moduleSize >> 1;

            int sampleDimension = borderWidth + (dimension - 1) * moduleSize;

            if (sampleDimension >= width || sampleDimension >= height)
            {
                throw new ReaderException();
            }

            // Now just read off the bits
            BitMatrix bits = new BitMatrix(dimension);

            for (int i = 0; i < dimension; i++)
            {
                int iOffset = borderWidth + i * moduleSize;
                for (int j = 0; j < dimension; j++)
                {
                    if (image.isBlack(borderWidth + j * moduleSize, iOffset))
                    {
                        bits.set(i, j);
                    }
                }
            }
            return(bits);
        }
Example #21
0
          private static BitMatrix sampleGrid(MonochromeBitmapSource image,
                                              ResultPoint topLeft,
                                              ResultPoint bottomLeft,
                                              ResultPoint bottomRight,
                                              int dimension) {

            // We make up the top right point for now, based on the others.
            // TODO: we actually found a fourth corner above and figured out which of two modules
            // it was the corner of. We could use that here and adjust for perspective distortion.
            float topRightX = (bottomRight.getX() - bottomLeft.getX()) + topLeft.getX();
            float topRightY = (bottomRight.getY() - bottomLeft.getY()) + topLeft.getY();

            // Note that unlike in the QR Code sampler, we didn't find the center of modules, but the
            // very corners. So there is no 0.5f here; 0.0f is right.
            GridSampler sampler = GridSampler.Instance;
            return sampler.sampleGrid(
                image,
                dimension,
                0.0f,
                0.0f,
                dimension,
                0.0f,
                dimension,
                dimension,
                0.0f,
                dimension,
                topLeft.getX(),
                topLeft.getY(),
                topRightX,
                topRightY,
                bottomRight.getX(),
                bottomRight.getY(),
                bottomLeft.getX(),
                bottomLeft.getY());
          }
        /**
           * 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();
        }
 public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
 {
     try {
       return doDecode(image, hints);
     } catch (ReaderException re) {
       bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
       if (tryHarder && image.isRotateSupported()) {
         MonochromeBitmapSource rotatedImage = image.rotateCounterClockwise();
         Result result = doDecode(rotatedImage, hints);
         // Record that we found it rotated 90 degrees CCW / 270 degrees CW
         System.Collections.Hashtable metadata = result.getResultMetadata();
         int orientation = 270;
         if (metadata != null && metadata.ContainsKey(ResultMetadataType.ORIENTATION)) {
           // But if we found it reversed in doDecode(), add in that result here:
           orientation = (orientation + ((int) metadata[ResultMetadataType.ORIENTATION])) % 360;
         }
         result.putMetadata(ResultMetadataType.ORIENTATION, orientation);
         return result;
       } else {
         throw re;
       }
     }
 }
Example #24
0
        /**
         * <p>Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
         * except it reads horizontally instead of vertically. This is used to cross-cross
         * check a vertical cross check and locate the real center of the alignment pattern.</p>
         */
        private float crossCheckHorizontal(int startJ, int centerI, int maxCount, int originalStateCountTotal)
        {
            MonochromeBitmapSource image = this.image;

            int maxJ = image.getWidth();

            int[] stateCount = getCrossCheckStateCount();

            int j = startJ;

            while (j >= 0 && image.isBlack(j, centerI))
            {
                stateCount[2]++;
                j--;
            }
            if (j < 0)
            {
                return(float.NaN);
            }
            while (j >= 0 && !image.isBlack(j, centerI) && stateCount[1] <= maxCount)
            {
                stateCount[1]++;
                j--;
            }
            if (j < 0 || stateCount[1] > maxCount)
            {
                return(float.NaN);
            }
            while (j >= 0 && image.isBlack(j, centerI) && stateCount[0] <= maxCount)
            {
                stateCount[0]++;
                j--;
            }
            if (stateCount[0] > maxCount)
            {
                return(float.NaN);
            }

            j = startJ + 1;
            while (j < maxJ && image.isBlack(j, centerI))
            {
                stateCount[2]++;
                j++;
            }
            if (j == maxJ)
            {
                return(float.NaN);
            }
            while (j < maxJ && !image.isBlack(j, centerI) && stateCount[3] < maxCount)
            {
                stateCount[3]++;
                j++;
            }
            if (j == maxJ || stateCount[3] >= maxCount)
            {
                return(float.NaN);
            }
            while (j < maxJ && image.isBlack(j, centerI) && stateCount[4] < maxCount)
            {
                stateCount[4]++;
                j++;
            }
            if (stateCount[4] >= maxCount)
            {
                return(float.NaN);
            }

            // If we found a finder-pattern-like section, but its size is significantly different than
            // the original, assume it's a false positive
            int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];

            if (5 * Math.Abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal)
            {
                return(float.NaN);
            }

            return(foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : float.NaN);
        }
Example #25
0
 public Detector(MonochromeBitmapSource image)
 {
     this.image = image;
 }
Example #26
0
 public Result decode(MonochromeBitmapSource image, System.Collections.Hashtable hints)
 {
     return(maybeReturnResult(ean13Reader.decode(image, hints)));
 }
          private Result decodeInternal(MonochromeBitmapSource image) {
              try
              {
                  int size = readers.Count;
                  for (int i = 0; i < size; i++)
                  {
                      Reader reader = (Reader)readers[i];
                      try
                      {
                          return reader.decode(image, hints);
                      }
                      catch (ReaderException re)
                      {
                          // continue
                      }
                  }

                  throw new ReaderException("");
              }
              catch (Exception e) {
                  throw new ReaderException(e.Message);
              }
          }
Example #28
0
 public Result decode(MonochromeBitmapSource image)
 {
     return(maybeReturnResult(ean13Reader.decode(image)));
 }
        /**
           * This method detects a Data Matrix code in a "pure" image -- that is, pure monochrome image
           * which contains only an unrotated, unskewed, image of a Data Matrix code, with some white border
           * around it. This is a specialized method that works exceptionally fast in this special
           * case.
           */
        private static BitMatrix extractPureBits(MonochromeBitmapSource image)
        {
            // Now need to determine module size in pixels

            int height = image.getHeight();
            int width = image.getWidth();
            int minDimension = Math.Min(height, width);

            // First, skip white border by tracking diagonally from the top left down and to the right:
            int borderWidth = 0;
            while (borderWidth < minDimension && !image.isBlack(borderWidth, borderWidth)) {
              borderWidth++;
            }
            if (borderWidth == minDimension) {
              throw new ReaderException();
            }

            // And then keep tracking across the top-left black module to determine module size
            int moduleEnd = borderWidth + 1;
            while (moduleEnd < width && image.isBlack(moduleEnd, borderWidth)) {
              moduleEnd++;
            }
            if (moduleEnd == width) {
              throw new ReaderException();
            }

            int moduleSize = moduleEnd - borderWidth;

            // And now find where the bottommost black module on the first column ends
            int columnEndOfSymbol = height - 1;
            while (columnEndOfSymbol >= 0 && !image.isBlack(borderWidth, columnEndOfSymbol)) {
                columnEndOfSymbol--;
            }
            if (columnEndOfSymbol < 0) {
              throw new ReaderException();
            }
            columnEndOfSymbol++;

            // Make sure width of barcode is a multiple of module size
            if ((columnEndOfSymbol - borderWidth) % moduleSize != 0) {
              throw new ReaderException();
            }
            int dimension = (columnEndOfSymbol - borderWidth) / moduleSize;

            // Push in the "border" by half the module width so that we start
            // sampling in the middle of the module. Just in case the image is a
            // little off, this will help recover.
            borderWidth += moduleSize >> 1;

            int sampleDimension = borderWidth + (dimension - 1) * moduleSize;
            if (sampleDimension >= width || sampleDimension >= height) {
              throw new ReaderException();
            }

            // Now just read off the bits
            BitMatrix bits = new BitMatrix(dimension);
            for (int i = 0; i < dimension; i++) {
              int iOffset = borderWidth + i * moduleSize;
              for (int j = 0; j < dimension; j++) {
                if (image.isBlack(borderWidth + j * moduleSize, iOffset)) {
                  bits.set(i, j);
                }
              }
            }
            return bits;
        }
Example #30
0
        /**
         * <p>After a horizontal scan finds a potential alignment pattern, this method
         * "cross-checks" by scanning down vertically through the center of the possible
         * alignment pattern to see if the same proportion is detected.</p>
         *
         * @param startI row where an alignment pattern was detected
         * @param centerJ center of the section that appears to cross an alignment pattern
         * @param maxCount maximum reasonable number of modules that should be
         * observed in any reading state, based on the results of the horizontal scan
         * @return vertical center of alignment pattern, or {@link Float#NaN} if not found
         */
        private float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal)
        {
            MonochromeBitmapSource image = this.image;

            int maxI = image.getHeight();

            int[] stateCount = crossCheckStateCount;
            stateCount[0] = 0;
            stateCount[1] = 0;
            stateCount[2] = 0;

            // Start counting up from center
            int i = startI;

            while (i >= 0 && image.isBlack(centerJ, i) && stateCount[1] <= maxCount)
            {
                stateCount[1]++;
                i--;
            }
            // If already too many modules in this state or ran off the edge:
            if (i < 0 || stateCount[1] > maxCount)
            {
                return(float.NaN);
            }
            while (i >= 0 && !image.isBlack(centerJ, i) && stateCount[0] <= maxCount)
            {
                stateCount[0]++;
                i--;
            }
            if (stateCount[0] > maxCount)
            {
                return(float.NaN);
            }

            // Now also count down from center
            i = startI + 1;
            while (i < maxI && image.isBlack(centerJ, i) && stateCount[1] <= maxCount)
            {
                stateCount[1]++;
                i++;
            }
            if (i == maxI || stateCount[1] > maxCount)
            {
                return(float.NaN);
            }
            while (i < maxI && !image.isBlack(centerJ, i) && stateCount[2] <= maxCount)
            {
                stateCount[2]++;
                i++;
            }
            if (stateCount[2] > maxCount)
            {
                return(float.NaN);
            }

            int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];

            if (5 * Math.Abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal)
            {
                return(float.NaN);
            }

            return(foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : float.NaN);
        }
Example #31
0
        private static BitMatrix sampleGrid(MonochromeBitmapSource image,
            ResultPoint topLeft,
            ResultPoint topRight,
            ResultPoint bottomLeft,
            ResultPoint alignmentPattern,
            int dimension)
        {
            float dimMinusThree = (float) dimension - 3.5f;
            float bottomRightX;
            float bottomRightY;
            float sourceBottomRightX;
            float sourceBottomRightY;
            if (alignmentPattern != null) {
              bottomRightX = alignmentPattern.getX();
              bottomRightY = alignmentPattern.getY();
              sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
            } else {
              // Don't have an alignment pattern, just make up the bottom-right point
              bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX();
              bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY();
              sourceBottomRightX = sourceBottomRightY = dimMinusThree;
            }

            GridSampler sampler = GridSampler.Instance;
            return sampler.sampleGrid(
                image,
                dimension,
                3.5f,
                3.5f,
                dimMinusThree,
                3.5f,
                sourceBottomRightX,
                sourceBottomRightY,
                3.5f,
                dimMinusThree,
                topLeft.getX(),
                topLeft.getY(),
                topRight.getX(),
                topRight.getY(),
                bottomRightX,
                bottomRightY,
                bottomLeft.getX(),
                bottomLeft.getY());
        }
Example #32
0
        /**
         * <p>Detects a QR Code in an image, simply.</p>
         *
         * @param hints optional hints to detector
         * @return {@link DetectorResult} encapsulating results of detecting a QR Code
         * @throws ReaderException if no QR Code can be found
         */
        public DetectorResult detect(System.Collections.Hashtable hints)
        {
            MonochromeBitmapSource image = this.image;

            if (!BlackPointEstimationMethod.TWO_D_SAMPLING.Equals(image.getLastEstimationMethod()))
            {
                image.estimateBlackPoint(BlackPointEstimationMethod.TWO_D_SAMPLING, 0);
            }

            FinderPatternFinder finder = new FinderPatternFinder(image);
            FinderPatternInfo   info   = finder.find(hints);

            FinderPattern topLeft    = info.getTopLeft();
            FinderPattern topRight   = info.getTopRight();
            FinderPattern bottomLeft = info.getBottomLeft();

            float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);

            if (moduleSize < 1.0f)
            {
                throw new ReaderException();
            }
            int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);

            Version provisionalVersion      = Version.getProvisionalVersionForDimension(dimension);
            int     modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;

            AlignmentPattern alignmentPattern = null;

            // Anything above version 1 has an alignment pattern
            if (provisionalVersion.getAlignmentPatternCenters().Length > 0)
            {
                // Guess where a "bottom right" finder pattern would have been
                float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
                float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();

                // Estimate that alignment pattern is closer by 3 modules
                // from "bottom right" to known top left location
                float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
                int   estAlignmentX       = (int)(topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX()));
                int   estAlignmentY       = (int)(topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY()));

                // Kind of arbitrary -- expand search radius before giving up
                for (int i = 4; i <= 16; i <<= 1)
                {
                    try {
                        alignmentPattern = findAlignmentInRegion(moduleSize,
                                                                 estAlignmentX,
                                                                 estAlignmentY,
                                                                 (float)i);
                        break;
                    } catch (ReaderException re) {
                        // try next round
                    }
                }
                if (alignmentPattern == null)
                {
                    throw new ReaderException();
                }
            }

            BitMatrix bits = sampleGrid(image, topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            ResultPoint[] points;
            if (alignmentPattern == null)
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight };
            }
            else
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern };
            }
            return(new DetectorResult(bits, points));
        }
 /**
    * <p>Creates a finder that will search the image for three finder patterns.</p>
    *
    * @param image image to search
    */
 public FinderPatternFinder(MonochromeBitmapSource image)
 {
     this.image = image;
     this.possibleCenters = new System.Collections.ArrayList();
     this.crossCheckStateCount = new int[5];
 }
 /**
    * Locates and decodes a Data Matrix code in an image.
    *
    * @return a String representing the content encoded by the Data Matrix code
    * @throws ReaderException if a Data Matrix code cannot be found, or cannot be decoded
    */
 public Result decode(MonochromeBitmapSource image)
 {
     return decode(image, null);
 }
Example #35
0
 public Detector(MonochromeBitmapSource image)
 {
     this.image = image;
 }
Example #36
0
        /**
         * <p>After a horizontal scan finds a potential finder pattern, this method
         * "cross-checks" by scanning down vertically through the center of the possible
         * finder pattern to see if the same proportion is detected.</p>
         *
         * @param startI row where a finder pattern was detected
         * @param centerJ center of the section that appears to cross a finder pattern
         * @param maxCount maximum reasonable number of modules that should be
         * observed in any reading state, based on the results of the horizontal scan
         * @return vertical center of finder pattern, or {@link Float#NaN} if not found
         */
        private float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal)
        {
            MonochromeBitmapSource image = this.image;

            int maxI = image.getHeight();

            int[] stateCount = getCrossCheckStateCount();

            // Start counting up from center
            int i = startI;

            while (i >= 0 && image.isBlack(centerJ, i))
            {
                stateCount[2]++;
                i--;
            }
            if (i < 0)
            {
                return(float.NaN);
            }
            while (i >= 0 && !image.isBlack(centerJ, i) && stateCount[1] <= maxCount)
            {
                stateCount[1]++;
                i--;
            }
            // If already too many modules in this state or ran off the edge:
            if (i < 0 || stateCount[1] > maxCount)
            {
                return(float.NaN);
            }
            while (i >= 0 && image.isBlack(centerJ, i) && stateCount[0] <= maxCount)
            {
                stateCount[0]++;
                i--;
            }
            if (stateCount[0] > maxCount)
            {
                return(float.NaN);
            }

            // Now also count down from center
            i = startI + 1;
            while (i < maxI && image.isBlack(centerJ, i))
            {
                stateCount[2]++;
                i++;
            }
            if (i == maxI)
            {
                return(float.NaN);
            }
            while (i < maxI && !image.isBlack(centerJ, i) && stateCount[3] < maxCount)
            {
                stateCount[3]++;
                i++;
            }
            if (i == maxI || stateCount[3] >= maxCount)
            {
                return(float.NaN);
            }
            while (i < maxI && image.isBlack(centerJ, i) && stateCount[4] < maxCount)
            {
                stateCount[4]++;
                i++;
            }
            if (stateCount[4] >= maxCount)
            {
                return(float.NaN);
            }

            // If we found a finder-pattern-like section, but its size is more than 20% different than
            // the original, assume it's a false positive
            int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];

            if (5 * Math.Abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal)
            {
                return(float.NaN);
            }

            return(foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : float.NaN);
        }