/// <summary>
      /// Decodes the multiple.
      /// </summary>
      /// <param name="image">The image.</param>
      /// <param name="hints">The hints.</param>
      /// <returns></returns>
      public Result[] decodeMultiple(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
      {
         var results = new List<Result>();
         var detectorResults = new MultiDetector(image.BlackMatrix).detectMulti(hints);
         foreach (DetectorResult detectorResult in detectorResults)
         {
            var decoderResult = getDecoder().decode(detectorResult.Bits, hints);
            if (decoderResult == null)
               continue;

            var points = detectorResult.Points;
            var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
            var byteSegments = decoderResult.ByteSegments;
            if (byteSegments != null)
            {
               result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
            }
            var ecLevel = decoderResult.ECLevel;
            if (ecLevel != null)
            {
               result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
            }
            if (decoderResult.StructuredAppend)
            {
               result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.StructuredAppendSequenceNumber);
               result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.StructuredAppendParity);
            }
            results.Add(result);
         }
         results = ProcessStructuredAppend(results);
         return results.Count == 0 ? EMPTY_RESULT_ARRAY : results.ToArray();
      }
Exemplo n.º 2
0
 public Result decode(BinaryBitmap image, System.Collections.Generic.Dictionary <Object,Object> hints)
 {
     DecoderResult decoderResult;
     ResultPoint[] points;
     if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE))
     {
         BitMatrix bits = extractPureBits(image.BlackMatrix);
         decoderResult = decoder.decode(bits);
         points = NO_POINTS;
     }
     else
     {
         DetectorResult detectorResult = new Detector(image.BlackMatrix).detect();
         decoderResult = decoder.decode(detectorResult.Bits);
         points = detectorResult.Points;
     }
     Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.DATAMATRIX);
     if (decoderResult.ByteSegments != null)
     {
         result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.ByteSegments);
     }
     if (decoderResult.ECLevel != null)
     {
         result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.ECLevel.ToString());
     }
     return result;
 }
Exemplo n.º 3
0
      /// <summary>
      /// Decodes the multiple.
      /// </summary>
      /// <param name="image">The image.</param>
      /// <param name="hints">The hints.</param>
      /// <returns></returns>
      public Result[] decodeMultiple(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
      {
         var results = new List<Result>();
         var detectorResults = new MultiDetector(image.BlackMatrix).detectMulti(hints);
         foreach (DetectorResult detectorResult in detectorResults)
         {
            var decoderResult = getDecoder().decode(detectorResult.Bits, hints);
            if (decoderResult == null)
               continue;

            var points = detectorResult.Points;
            // If the code was mirrored: swap the bottom-left and the top-right points.
            var data = decoderResult.Other as QRCodeDecoderMetaData;
            if (data != null)
            {
               data.applyMirroredCorrection(points);
            }
            var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
            var byteSegments = decoderResult.ByteSegments;
            if (byteSegments != null)
            {
               result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
            }
            var ecLevel = decoderResult.ECLevel;
            if (ecLevel != null)
            {
               result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
            }
            if (decoderResult.StructuredAppend)
            {
               result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.StructuredAppendSequenceNumber);
               result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.StructuredAppendParity);
            }
            results.Add(result);
         }
         if (results.Count == 0)
         {
            return null;
         }
         results = ProcessStructuredAppend(results);
         return results.ToArray();
      }
Exemplo n.º 4
0
        public Result[] decodeMultiple(BinaryBitmap image, Dictionary<DecodeHintType, Object> hints)
        {
            var results = new List<Result>(10);

            DetectorResult[] detectorResult = new MultiDetector(image.BlackMatrix).detectMulti(hints);

            foreach (DetectorResult t in detectorResult)
            {
                try
                {
                    DecoderResult decoderResult = Decoder.decode(t.Bits);
                    ResultPoint[] points = t.Points;
                    var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);

                    if (decoderResult.ByteSegments != null)
                    {
                        result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.ByteSegments);
                    }
                    if (decoderResult.ECLevel != null)
                    {
                        result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.ECLevel.ToString());
                    }
                    results.Add(result);
                }
                catch (ReaderException)
                {
                    // ignore and continue 
                }
            }
            if ((results.Count == 0))
            {
                return EMPTY_RESULT_ARRAY;
            }

            var resultArray = new Result[results.Count];
            for (int i = 0; i < results.Count; i++)
            {
                resultArray[i] = (Result) results[i];
            }
            return resultArray;
        }
Exemplo n.º 5
0
        public Result decode(MonochromeBitmapSource image, Hashtable hints)
        {
            try{
                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(hints);
                  decoderResult = decoder.decode(detectorResult.getBits());
                  points = detectorResult.getPoints();
                }

                Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
                if (decoderResult.getByteSegments() != null) {
                  result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
                }
                return result;
              }catch(Exception e){
                throw new ReaderException(e.Message);
              }
        }
Exemplo n.º 6
0
      /// <summary>
      /// Locates and decodes a barcode in some format within an image. This method also accepts
      /// hints, each possibly associated to some data, which may help the implementation decode.
      /// </summary>
      /// <param name="image">image of barcode to decode</param>
      /// <param name="hints">passed as a <see cref="IDictionary{TKey, TValue}"/> from <see cref="DecodeHintType"/>
      /// to arbitrary data. The
      /// meaning of the data depends upon the hint type. The implementation may or may not do
      /// anything with these hints.</param>
      /// <returns>
      /// String which the barcode encodes
      /// </returns>
      public Result decode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
      {
         DecoderResult decoderResult;
         ResultPoint[] points;
         if (image == null || image.BlackMatrix == null)
         {
            // something is wrong with the image
            return null;
         }
         if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE))
         {
            BitMatrix bits = extractPureBits(image.BlackMatrix);
            if (bits == null)
               return null;
            decoderResult = decoder.decode(bits, hints);
            points = NO_POINTS;
         }
         else
         {
            DetectorResult detectorResult = new Detector(image.BlackMatrix).detect(hints);
            if (detectorResult == null)
               return null;
            decoderResult = decoder.decode(detectorResult.Bits, hints);
            points = detectorResult.Points;
         }
         if (decoderResult == null)
            return null;

         Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
         IList<byte[]> byteSegments = decoderResult.ByteSegments;
         if (byteSegments != null)
         {
            result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
         }
         var ecLevel = decoderResult.ECLevel;
         if (ecLevel != null)
         {
            result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
         }
         return result;
      }
Exemplo n.º 7
0
      /// <summary>
      ///   <p>Like decodeRow(int, BitArray, java.util.Map), but
      /// allows caller to inform method about where the UPC/EAN start pattern is
      /// found. This allows this to be computed once and reused across many implementations.</p>
      /// </summary>
      /// <param name="rowNumber">row index into the image</param>
      /// <param name="row">encoding of the row of the barcode image</param>
      /// <param name="startGuardRange">start/end column where the opening start pattern was found</param>
      /// <param name="hints">optional hints that influence decoding</param>
      /// <returns><see cref="Result"/> encapsulating the result of decoding a barcode in the row</returns>
      virtual public Result decodeRow(int rowNumber,
                              BitArray row,
                              int[] startGuardRange,
                              IDictionary<DecodeHintType, object> hints)
      {
         var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null :
             (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
            ));
         }

         var result = decodeRowStringBuffer;
         result.Length = 0;
         var endStart = decodeMiddle(row, startGuardRange, result);
         if (endStart < 0)
            return null;

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                endStart, rowNumber
            ));
         }

         var endRange = decodeEnd(row, endStart);
         if (endRange == null)
            return null;

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                (endRange[0] + endRange[1]) / 2.0f, rowNumber
            ));
         }


         // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
         // spec might want more whitespace, but in practice this is the maximum we can count on.
         var end = endRange[1];
         var quietEnd = end + (end - endRange[0]);
         if (quietEnd >= row.Size || !row.isRange(end, quietEnd, false))
         {
            return null;
         }

         var resultString = result.ToString();
         // UPC/EAN should never be less than 8 chars anyway
         if (resultString.Length < 8)
         {
            return null;
         }
         if (!checkChecksum(resultString))
         {
            return null;
         }

         var left = (startGuardRange[1] + startGuardRange[0]) / 2.0f;
         var right = (endRange[1] + endRange[0]) / 2.0f;
         var format = BarcodeFormat;
         var decodeResult = new Result(resultString,
                                          null, // no natural byte representation for these barcodes
                                          new ResultPoint[]
                                             {
                                                new ResultPoint(left, rowNumber),
                                                new ResultPoint(right, rowNumber)
                                             },
                                          format);

         var extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);
         if (extensionResult != null)
         {
            decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.Text);
            decodeResult.putAllMetadata(extensionResult.ResultMetadata);
            decodeResult.addResultPoints(extensionResult.ResultPoints);
            int extensionLength = extensionResult.Text.Length;
            int[] allowedExtensions = hints != null && hints.ContainsKey(DecodeHintType.ALLOWED_EAN_EXTENSIONS) ? 
               (int[]) hints[DecodeHintType.ALLOWED_EAN_EXTENSIONS] : null;
            if (allowedExtensions != null)
            {
               bool valid = false;
               foreach (int length in allowedExtensions)
               {
                  if (extensionLength == length)
                  {
                     valid = true;
                     break;
                  }
               }
               if (!valid)
               {
                  return null;
               }
            }
         }

         if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A)
         {
            String countryID = eanManSupport.lookupCountryIdentifier(resultString);
            if (countryID != null)
            {
               decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
            }
         }

         return decodeResult;
      }
Exemplo n.º 8
0
 /// <summary>
 /// Decode the specified image, with the hints and optionally multiple barcodes.
 /// Based on Owen's Comments in <see cref="ZXing.ReaderException"/>, this method has been modified to continue silently
 /// if a barcode was not decoded where it was detected instead of throwing a new exception object.
 /// </summary>
 /// <param name="image">Image.</param>
 /// <param name="hints">Hints.</param>
 /// <param name="multiple">If set to <c>true</c> multiple.</param>
 private static Result[] Decode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints, bool multiple)
 {
     List<Result> results = new List<Result>();
     PDF417DetectorResult detectorResult = Detector.Detect(image, hints, multiple);
     foreach (ResultPoint[] points in detectorResult.Points)
     {
         DecoderResult decoderResult = PDF417ScanningDecoder.Decode(detectorResult.Bits, points[4], points[5],
                                                                    points[6], points[7], GetMinCodewordWidth(points), GetMaxCodewordWidth(points));
         if (decoderResult == null)
         {
             // See comments re: Exceptions above
             // continue;
             throw ReaderException.Instance;
         }
         System.Diagnostics.Debug.WriteLine("Result " + points.ToString() + " > " + decoderResult.Text + " " + decoderResult.RawBytes);
         Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.PDF_417);
         result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.ECLevel);
         PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata)decoderResult.Other;
         if (pdf417ResultMetadata != null)
         {
             result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata);
         }
         results.Add(result);
     }
     return results.ToArray();
 }
Exemplo n.º 9
0
 /// <summary>
 /// Decode the specified image, with the hints and optionally multiple barcodes.
 /// Based on Owen's Comments in <see cref="ZXing.ReaderException"/>, this method has been modified to continue silently
 /// if a barcode was not decoded where it was detected instead of throwing a new exception object.
 /// </summary>
 /// <param name="image">Image.</param>
 /// <param name="hints">Hints.</param>
 /// <param name="multiple">If set to <c>true</c> multiple.</param>
 private static Result[] decode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints, bool multiple)
 {
    var results = new List<Result>();
    var detectorResult = Detector.detect(image, hints, multiple);
    if (detectorResult != null)
    {
       foreach (var points in detectorResult.Points)
       {
          var decoderResult = PDF417ScanningDecoder.decode(detectorResult.Bits, points[4], points[5],
                                                           points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points));
          if (decoderResult == null)
          {
             continue;
          }
          var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.PDF_417);
          result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.ECLevel);
          var pdf417ResultMetadata = (PDF417ResultMetadata) decoderResult.Other;
          if (pdf417ResultMetadata != null)
          {
             result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata);
          }
          results.Add(result);
       }
    }
    return results.ToArray();
 }
Exemplo n.º 10
0
      /// <summary>
      /// Locates and decodes a barcode in some format within an image. This method also accepts
      /// hints, each possibly associated to some data, which may help the implementation decode.
      /// </summary>
      /// <param name="image">image of barcode to decode</param>
      /// <param name="hints">passed as a <see cref="IDictionary{TKey, TValue}"/> from <see cref="DecodeHintType"/>
      /// to arbitrary data. The
      /// meaning of the data depends upon the hint type. The implementation may or may not do
      /// anything with these hints.</param>
      /// <returns>
      /// String which the barcode encodes
      /// </returns>
      public Result decode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
      {
         DecoderResult decoderResult;
         ResultPoint[] points;
         if (image == null || image.BlackMatrix == null)
         {
            // something is wrong with the image
            return null;
         }
         if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE))
         {
            var bits = extractPureBits(image.BlackMatrix);
            if (bits == null)
               return null;
            decoderResult = decoder.decode(bits, hints);
            points = NO_POINTS;
         }
         else
         {
            var detectorResult = new Detector(image.BlackMatrix).detect(hints);
            if (detectorResult == null)
               return null;
            decoderResult = decoder.decode(detectorResult.Bits, hints);
            points = detectorResult.Points;
         }
         if (decoderResult == null)
            return null;

         // If the code was mirrored: swap the bottom-left and the top-right points.
         var data = decoderResult.Other as QRCodeDecoderMetaData;
         if (data != null)
         {
            data.applyMirroredCorrection(points);
         }

         var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
         var byteSegments = decoderResult.ByteSegments;
         if (byteSegments != null)
         {
            result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
         }
         var ecLevel = decoderResult.ECLevel;
         if (ecLevel != null)
         {
            result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
         }
         if (decoderResult.StructuredAppend)
         {
            result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.StructuredAppendSequenceNumber);
            result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.StructuredAppendParity);
         }
         return result;
      }
Exemplo n.º 11
0
      /// <summary>
      /// <p>Like decodeRow(int, BitArray, java.util.Map), but
      /// allows caller to inform method about where the UPC/EAN start pattern is
      /// found. This allows this to be computed once and reused across many implementations.</p>
      /// </summary>
      virtual public Result decodeRow(int rowNumber,
                              BitArray row,
                              int[] startGuardRange,
                              IDictionary<DecodeHintType, object> hints)
      {

         ResultPointCallback resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null :
             (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
            ));
         }

         StringBuilder result = decodeRowStringBuffer;
         result.Length = 0;
         int endStart = decodeMiddle(row, startGuardRange, result);
         if (endStart < 0)
            return null;

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                endStart, rowNumber
            ));
         }

         int[] endRange = decodeEnd(row, endStart);
         if (endRange == null)
            return null;

         if (resultPointCallback != null)
         {
            resultPointCallback(new ResultPoint(
                (endRange[0] + endRange[1]) / 2.0f, rowNumber
            ));
         }


         // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
         // spec might want more whitespace, but in practice this is the maximum we can count on.
         int end = endRange[1];
         int quietEnd = end + (end - endRange[0]);
         if (quietEnd >= row.Size || !row.isRange(end, quietEnd, false))
         {
            return null;
         }

         String resultString = result.ToString();
         if (!checkChecksum(resultString))
         {
            return null;
         }

         float left = (startGuardRange[1] + startGuardRange[0]) / 2.0f;
         float right = (endRange[1] + endRange[0]) / 2.0f;
         BarcodeFormat format = BarcodeFormat;
         Result decodeResult = new Result(resultString,
                                          null, // no natural byte representation for these barcodes
                                          new ResultPoint[]
                                             {
                                                new ResultPoint(left, rowNumber),
                                                new ResultPoint(right, rowNumber)
                                             },
                                          format);

         Result extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);
         if (extensionResult != null)
         {
            decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.Text);
            decodeResult.putAllMetadata(extensionResult.ResultMetadata);
            decodeResult.addResultPoints(extensionResult.ResultPoints);
         }

         if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A)
         {
            String countryID = eanManSupport.lookupCountryIdentifier(resultString);
            if (countryID != null)
            {
               decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
            }
         }

         return decodeResult;
      }
Exemplo n.º 12
0
 private List<Result> ProcessStructuredAppend(List<Result> results)
 {
    bool hasSA = false;
    // first, check, if there is at least on SA result in the list
    foreach (var result in results)
    {
       if (result.ResultMetadata.ContainsKey(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE))
       {
          hasSA = true;
          break;
       }
    }
    if (!hasSA)
    {
       return results;
    }
    // it is, second, split the lists and built a new result list
    var newResults = new List<Result>();
    var saResults = new List<Result>();
    foreach (var result in results)
    {
       newResults.Add(result);
       if (result.ResultMetadata.ContainsKey(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE))
       {
          saResults.Add(result);
       }
    }
    // sort and concatenate the SA list items
    saResults.Sort(SaSequenceSort);
    var concatedText = String.Empty;
    var rawBytesLen = 0;
    int byteSegmentLength = 0;
    foreach (var saResult in saResults)
    {
       concatedText += saResult.Text;
       rawBytesLen += saResult.RawBytes.Length;
       if (saResult.ResultMetadata.ContainsKey(ResultMetadataType.BYTE_SEGMENTS))
       {
          foreach (var segment in (IEnumerable<byte[]>) saResult.ResultMetadata[ResultMetadataType.BYTE_SEGMENTS])
          {
             byteSegmentLength += segment.Length;
          }
       }
    }
    var newRawBytes = new byte[rawBytesLen];
    byte[] newByteSegment = new byte[byteSegmentLength];
    int newRawBytesIndex = 0;
    int byteSegmentIndex = 0;
    foreach (var saResult in saResults)
    {
       Array.Copy(saResult.RawBytes, 0, newRawBytes, newRawBytesIndex, saResult.RawBytes.Length);
       newRawBytesIndex += saResult.RawBytes.Length;
       if (saResult.ResultMetadata.ContainsKey(ResultMetadataType.BYTE_SEGMENTS))
       {
          foreach (var segment in (IEnumerable<byte[]>) saResult.ResultMetadata[ResultMetadataType.BYTE_SEGMENTS])
          {
             Array.Copy(segment, 0, newByteSegment, byteSegmentIndex, segment.Length);
             byteSegmentIndex += segment.Length;
          }
       }
    }
    Result newResult = new Result(concatedText, newRawBytes, NO_POINTS, BarcodeFormat.QR_CODE);
    if (byteSegmentLength > 0)
    {
       var byteSegmentList = new List<byte[]>();
       byteSegmentList.Add(newByteSegment);
       newResult.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegmentList);
    }
    newResults.Add(newResult);
    return newResults;
 }