/// <summary> <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly
        /// white, in an image.</p>
        ///
        /// </summary>
        /// <returns> {@link ResultPoint}[] describing the corners of the rectangular region. The first and
        /// last points are opposed on the diagonal, as are the second and third. The first point will be
        /// the topmost point and the last, the bottommost. The second point will be leftmost and the
        /// third, the rightmost
        /// </returns>
        /// <throws>  ReaderException if no Data Matrix Code can be found </throws>
        public ResultPoint[] detect()
        {
            int height     = image.Height;
            int width      = image.Width;
            int halfHeight = height >> 1;
            int halfWidth  = width >> 1;
            int deltaY     = System.Math.Max(1, height / (MAX_MODULES << 3));
            int deltaX     = System.Math.Max(1, width / (MAX_MODULES << 3));

            int         top    = 0;
            int         bottom = height;
            int         left   = 0;
            int         right  = width;
            ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth >> 1);

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            top = (int)pointA.Y - 1;
            ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right, halfHeight, 0, top, bottom, halfHeight >> 1);

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            left = (int)pointB.X - 1;
            ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right, halfHeight, 0, top, bottom, halfHeight >> 1);

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            right = (int)pointC.X + 1;
            ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, deltaY, top, bottom, halfWidth >> 1);

            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            bottom = (int)pointD.Y + 1;

            // Go try to find point A again with better information -- might have been off at first.
            pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth >> 2);

            return(new ResultPoint[] { pointA, pointB, pointC, pointD });
        }
Exemplo n.º 2
0
        public virtual PerspectiveTransform createTransform(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint alignmentPattern, int dimension)
        {
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float dimMinusThree = (float)dimension - 3.5f;
            float bottomRightX;
            float bottomRightY;
            float sourceBottomRightX;
            float sourceBottomRightY;

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

            PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, topLeft.X, topLeft.Y, topRight.X, topRight.Y, bottomRightX, bottomRightY, bottomLeft.X, bottomLeft.Y);

            return(transform);
        }
Exemplo n.º 3
0
        private static BitMatrix sampleGrid(BitMatrix matrix, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight, int dimension)
        {
            // Note that unlike 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(matrix, dimension, 0.0f, 0.0f, dimension, 0.0f, dimension, dimension, 0.0f, dimension, topLeft.X, topLeft.Y, topRight.X, topRight.Y, bottomRight.X, bottomRight.Y, bottomLeft.X, bottomLeft.Y));            // p4FromY
        }
Exemplo n.º 4
0
        /// <summary> <p>Estimates module size (pixels in a module) based on the Start and End
        /// finder patterns.</p>
        ///
        /// </summary>
        /// <param name="vertices">an array of vertices:
        /// vertices[0] x, y top left barcode
        /// vertices[1] x, y bottom left barcode
        /// vertices[2] x, y top right barcode
        /// vertices[3] x, y bottom right barcode
        /// vertices[4] x, y top left codeword area
        /// vertices[5] x, y bottom left codeword area
        /// vertices[6] x, y top right codeword area
        /// vertices[7] x, y bottom right codeword area
        /// </param>
        /// <returns> the module size.
        /// </returns>
        private static float computeModuleWidth(ResultPoint[] vertices)
        {
            float pixels1      = ResultPoint.distance(vertices[0], vertices[4]);
            float pixels2      = ResultPoint.distance(vertices[1], vertices[5]);
            float moduleWidth1 = (pixels1 + pixels2) / (17 * 2.0f);
            float pixels3      = ResultPoint.distance(vertices[6], vertices[2]);
            float pixels4      = ResultPoint.distance(vertices[7], vertices[3]);
            float moduleWidth2 = (pixels3 + pixels4) / (18 * 2.0f);

            return((moduleWidth1 + moduleWidth2) / 2.0f);
        }
Exemplo n.º 5
0
 private static Result translateResultPoints(Result result, int xOffset, int yOffset)
 {
     ResultPoint[] oldResultPoints = result.ResultPoints;
     ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.Length];
     for (int i = 0; i < oldResultPoints.Length; i++)
     {
         ResultPoint oldPoint = oldResultPoints[i];
         newResultPoints[i] = new ResultPoint(oldPoint.X + xOffset, oldPoint.Y + yOffset);
     }
     return(new Result(result.Text, result.RawBytes, newResultPoints, result.BarcodeFormat));
 }
Exemplo n.º 6
0
        /// <summary> Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.</summary>
        private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to)
        {
            // See QR Code Detector, sizeOfBlackWhiteBlackRun()
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int fromX = (int)from.X;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int fromY = (int)from.Y;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int toX = (int)to.X;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int  toY   = (int)to.Y;
            bool steep = System.Math.Abs(toY - fromY) > System.Math.Abs(toX - fromX);

            if (steep)
            {
                int temp = fromX;
                fromX = fromY;
                fromY = temp;
                temp  = toX;
                toX   = toY;
                toY   = temp;
            }

            int  dx          = System.Math.Abs(toX - fromX);
            int  dy          = System.Math.Abs(toY - fromY);
            int  error       = -dx >> 1;
            int  ystep       = fromY < toY?1:-1;
            int  xstep       = fromX < toX?1:-1;
            int  transitions = 0;
            bool inBlack     = image.get_Renamed(steep?fromY:fromX, steep?fromX:fromY);

            for (int x = fromX, y = fromY; x != toX; x += xstep)
            {
                bool isBlack = image.get_Renamed(steep?y:x, steep?x:y);
                if (isBlack != inBlack)
                {
                    transitions++;
                    inBlack = isBlack;
                }
                error += dy;
                if (error > 0)
                {
                    if (y == toY)
                    {
                        break;
                    }
                    y     += ystep;
                    error -= dx;
                }
            }
            return(new ResultPointsAndTransitions(from, to, transitions));
        }
Exemplo n.º 7
0
        /// <summary> Because we scan horizontally to detect the start and stop patterns, the vertical component of
        /// the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.
        /// This method moves those points back onto the edges of the theoretically perfect bounding
        /// quadrilateral if needed.
        ///
        /// </summary>
        /// <param name="vertices">The eight vertices located by findVertices().
        /// </param>
        private static void  correctCodeWordVertices(ResultPoint[] vertices, bool upsideDown)
        {
            float skew = vertices[4].Y - vertices[6].Y;

            if (upsideDown)
            {
                skew = -skew;
            }
            if (skew > SKEW_THRESHOLD)
            {
                // Fix v4
                float length     = vertices[4].X - vertices[0].X;
                float deltax     = vertices[6].X - vertices[0].X;
                float deltay     = vertices[6].Y - vertices[0].Y;
                float correction = length * deltay / deltax;
                vertices[4] = new ResultPoint(vertices[4].X, vertices[4].Y + correction);
            }
            else if (-skew > SKEW_THRESHOLD)
            {
                // Fix v6
                float length     = vertices[2].X - vertices[6].X;
                float deltax     = vertices[2].X - vertices[4].X;
                float deltay     = vertices[2].Y - vertices[4].Y;
                float correction = length * deltay / deltax;
                vertices[6] = new ResultPoint(vertices[6].X, vertices[6].Y - correction);
            }

            skew = vertices[7].Y - vertices[5].Y;
            if (upsideDown)
            {
                skew = -skew;
            }
            if (skew > SKEW_THRESHOLD)
            {
                // Fix v5
                float length     = vertices[5].X - vertices[1].X;
                float deltax     = vertices[7].X - vertices[1].X;
                float deltay     = vertices[7].Y - vertices[1].Y;
                float correction = length * deltay / deltax;
                vertices[5] = new ResultPoint(vertices[5].X, vertices[5].Y + correction);
            }
            else if (-skew > SKEW_THRESHOLD)
            {
                // Fix v7
                float length     = vertices[3].X - vertices[7].X;
                float deltax     = vertices[3].X - vertices[5].X;
                float deltay     = vertices[3].Y - vertices[5].Y;
                float correction = length * deltay / deltax;
                vertices[7] = new ResultPoint(vertices[7].X, vertices[7].Y - correction);
            }
        }
        public void AddPossibleResultPoint(com.google.zxing.ResultPoint point)
        {
            var points = possibleResultPoints;

            lock (points)
            {
                points.Add(point);
                var size = points.Count;
                if (size > MAX_RESULT_POINTS)
                {
                    points.RemoveRange(0, size - MAX_RESULT_POINTS / 2);
                }
            }
        }
Exemplo n.º 9
0
        private static BitMatrix sampleGrid(BitMatrix 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.X - bottomLeft.X) + topLeft.X;
            float topRightY = (bottomRight.Y - bottomLeft.Y) + topLeft.Y;

            // 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.X, topLeft.Y, topRightX, topRightY, bottomRight.X, bottomRight.Y, bottomLeft.X, bottomLeft.Y));
        }
Exemplo n.º 10
0
        /// <summary> Computes the dimension (number of modules in a row) of the PDF417 Code
        /// based on vertices of the codeword area and estimated module size.
        ///
        /// </summary>
        /// <param name="topLeft">    of codeword area
        /// </param>
        /// <param name="topRight">   of codeword area
        /// </param>
        /// <param name="bottomLeft"> of codeword area
        /// </param>
        /// <param name="bottomRight">of codeword are
        /// </param>
        /// <param name="moduleWidth">estimated module size
        /// </param>
        /// <returns> the number of modules in a row.
        /// </returns>
        private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth)
        {
            int topRowDimension    = round(ResultPoint.distance(topLeft, topRight) / moduleWidth);
            int bottomRowDimension = round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth);

            return(((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17);

            /*
             * int topRowDimension = round(ResultPoint.distance(topLeft,
             * topRight)); //moduleWidth); int bottomRowDimension =
             * round(ResultPoint.distance(bottomLeft, bottomRight)); //
             * moduleWidth); int dimension = ((topRowDimension + bottomRowDimension)
             * >> 1); // Round up to nearest 17 modules i.e. there are 17 modules per
             * codeword //int dimension = ((((topRowDimension + bottomRowDimension) >>
             * 1) + 8) / 17) * 17; return dimension;
             */
        }
Exemplo n.º 11
0
        // Note that we don't try rotation without the try harder flag, even if rotation was supported.
        public virtual Result decode(BinaryBitmap image, System.Collections.Hashtable hints)
        {
            var retval = doDecode(image, hints);

            if (retval.HasValue())
            {
                return(retval);
            }
            else
            {
                bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
                if (tryHarder && image.RotateSupported)
                {
                    BinaryBitmap rotatedImage = image.rotateCounterClockwise();
                    Result       result       = doDecode(rotatedImage, hints);

                    if (result == null)
                    {
                        return(null);
                    }

                    // Record that we found it rotated 90 degrees CCW / 270 degrees CW
                    System.Collections.Hashtable metadata = result.ResultMetadata;
                    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 + ((System.Int32)metadata[ResultMetadataType.ORIENTATION])) % 360;
                    }
                    result.putMetadata(ResultMetadataType.ORIENTATION, (System.Object)orientation);
                    // Update result points
                    ResultPoint[] points = result.ResultPoints;
                    int           height = rotatedImage.Height;
                    for (int i = 0; i < points.Length; i++)
                    {
                        points[i] = new ResultPoint(height - points[i].Y - 1, points[i].X);
                    }
                    return(result);
                }
                else
                {
                    return(null);
                }
            }
        }
Exemplo n.º 12
0
        /// <summary> <p>Estimates module size based on two finder patterns -- it uses
        /// {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
        /// width of each, measuring along the axis between their centers.</p>
        /// </summary>
        private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern)
        {
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern.X, (int)pattern.Y, (int)otherPattern.X, (int)otherPattern.Y);
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern.X, (int)otherPattern.Y, (int)pattern.X, (int)pattern.Y);

            if (System.Single.IsNaN(moduleSizeEst1))
            {
                return(moduleSizeEst2 / 7.0f);
            }
            if (System.Single.IsNaN(moduleSizeEst2))
            {
                return(moduleSizeEst1 / 7.0f);
            }
            // Average them, and divide by 7 since we've counted the width of 3 black modules,
            // and 1 white and 1 black module on either side. Ergo, divide sum by 14.
            return((moduleSizeEst1 + moduleSizeEst2) / 14.0f);
        }
Exemplo n.º 13
0
 // Note that we don't try rotation without the try harder flag, even if rotation was supported.
 // public virtual Result decode(BinaryBitmap image, System.Collections.Hashtable hints) // commented by .net follower (http://dotnetfollower.com)
 public virtual Result decode(BinaryBitmap image, System.Collections.Generic.Dictionary <Object, Object> hints) // added by .net follower (http://dotnetfollower.com)
 {
     try
     {
         return(doDecode(image, hints));
     }
     catch (ReaderException re)
     {
         bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
         if (tryHarder && image.RotateSupported)
         {
             BinaryBitmap 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.ResultMetadata; // commented by .net follower (http://dotnetfollower.com)
             System.Collections.Generic.Dictionary <Object, Object> metadata = result.ResultMetadata; // added by .net follower (http://dotnetfollower.com)
             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 + ((System.Int32)metadata[ResultMetadataType.ORIENTATION])) % 360;
             }
             result.putMetadata(ResultMetadataType.ORIENTATION, (System.Object)orientation);
             // Update result points
             ResultPoint[] points = result.ResultPoints;
             int           height = rotatedImage.Height;
             for (int i = 0; i < points.Length; i++)
             {
                 points[i] = new ResultPoint(height - points[i].Y - 1, points[i].X);
             }
             return(result);
         }
         else
         {
             throw re;
         }
     }
 }
Exemplo n.º 14
0
        /// <summary> <p>Computes the dimension (number of modules on a size) of the QR Code based on the position
        /// of the finder patterns and estimated module size.</p>
        /// </summary>
        protected internal static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize)
        {
            int tltrCentersDimension = round(ResultPoint.distance(topLeft, topRight) / moduleSize);
            int tlblCentersDimension = round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
            int dimension            = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;

            switch (dimension & 0x03)
            {
            // mod 4
            case 0:
                dimension++;
                break;
            // 1? do nothing

            case 2:
                dimension--;
                break;

            case 3:
                throw ReaderException.Instance;
            }
            return(dimension);
        }
Exemplo n.º 15
0
		// Note that we don't try rotation without the try harder flag, even if rotation was supported.
		public virtual Result decode(BinaryBitmap 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.RotateSupported)
				{
					BinaryBitmap 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.ResultMetadata;
					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 + ((System.Int32) metadata[ResultMetadataType.ORIENTATION])) % 360;
					}
					result.putMetadata(ResultMetadataType.ORIENTATION, (System.Object) orientation);
					// Update result points
					ResultPoint[] points = result.ResultPoints;
					int height = rotatedImage.Height;
					for (int i = 0; i < points.Length; i++)
					{
						points[i] = new ResultPoint(height - points[i].Y - 1, points[i].X);
					}
					return result;
				}
				else
				{
					throw re;
				}
			}
		}
Exemplo n.º 16
0
 /// <summary> Increments the Integer associated with a key by one.</summary>
 private static void  increment(System.Collections.Hashtable table, ResultPoint key)
 {
     //System.Int32 value_Renamed = (System.Int32) table[key];
     ////UPGRADE_TODO: The 'System.Int32' structure does not have an equivalent to NULL. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1291'"
     //table[key] = value_Renamed == null?INTEGERS[1]:INTEGERS[value_Renamed + 1];
     // Redivivus.in Java to c# Porting update
     // 30/01/2010
     // Added
     // START
     System.Int32 value_Renamed = 0;
     try
     {
         if (table.Count > 0)
         {
             value_Renamed = (System.Int32)table[key];
         }
     }
     catch
     {
         value_Renamed = 0;
     }
     table[key] = value_Renamed == 0 ? INTEGERS[1] : INTEGERS[value_Renamed + 1];
     //END
 }
Exemplo n.º 17
0
        protected internal virtual DetectorResult processFinderPatternInfo(FinderPatternInfo info)
        {
            FinderPattern topLeft = info.TopLeft;
            FinderPattern topRight = info.TopRight;
            FinderPattern bottomLeft = info.BottomLeft;

            float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
            if (moduleSize < 1.0f)
            {
                throw ReaderException.Instance;
            }
            int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
            Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
            int modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7;

            AlignmentPattern alignmentPattern = null;
            // Anything above version 1 has an alignment pattern
            if (provisionalVersion.AlignmentPatternCenters.Length > 0)
            {

                // Guess where a "bottom right" finder pattern would have been
                float bottomRightX = topRight.X - topLeft.X + bottomLeft.X;
                float bottomRightY = topRight.Y - topLeft.Y + bottomLeft.Y;

                // Estimate that alignment pattern is closer by 3 modules
                // from "bottom right" to known top left location
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                float correctionToTopLeft = 1.0f - 3.0f / (float) modulesBetweenFPCenters;
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                int estAlignmentX = (int) (topLeft.X + correctionToTopLeft * (bottomRightX - topLeft.X));
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                int estAlignmentY = (int) (topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y));

                // Kind of arbitrary -- expand search radius before giving up
                for (int i = 4; i <= 16; i <<= 1)
                {
                    try
                    {
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float) i);
                        break;
                    }
                    catch (ReaderException)
                    {
                        // try next round
                    }
                }
                // If we didn't find alignment pattern... well try anyway without it
            }

            PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            BitMatrix bits = sampleGrid(image, transform, 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);
        }
Exemplo n.º 18
0
        /// <summary> <p>Computes the dimension (number of modules on a size) of the QR Code based on the position
        /// of the finder patterns and estimated module size.</p>
        /// </summary>
        protected internal static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize)
        {
            int tltrCentersDimension = round(ResultPoint.distance(topLeft, topRight) / moduleSize);
            int tlblCentersDimension = round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
            int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
            switch (dimension & 0x03)
            {

                // mod 4
                case 0:
                    dimension++;
                    break;
                    // 1? do nothing

                case 2:
                    dimension--;
                    break;

                case 3:
                    throw ReaderException.Instance;
                }
            return dimension;
        }
Exemplo n.º 19
0
        private static PerspectiveTransform createTransform(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.X;
              bottomRightY = alignmentPattern.Y;
              sourceBottomRightX = dimMinusThree - 3.0f;
              sourceBottomRightY = sourceBottomRightX;
            }
            else
            {
              // Don't have an alignment pattern, just make up the bottom-right point
              bottomRightX = (topRight.X - topLeft.X) + bottomLeft.X;
              bottomRightY = (topRight.Y - topLeft.Y) + bottomLeft.Y;
              sourceBottomRightX = dimMinusThree;
              sourceBottomRightY = dimMinusThree;
            }

            return PerspectiveTransform.quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, topLeft.X, topLeft.Y, topRight.X, topRight.Y, bottomRightX, bottomRightY, bottomLeft.X, bottomLeft.Y);
        }
Exemplo n.º 20
0
        /// <returns> the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
        /// those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
        /// size differs from the average among those patterns the least
        /// </returns>
        /// <throws>  ReaderException if 3 such finder patterns do not exist </throws>
        private FinderPattern[][] selectBestPatterns()
        {
            // System.Collections.ArrayList possibleCenters = PossibleCenters; // commented by .net follower (http://dotnetfollower.com)
            System.Collections.Generic.List <Object> possibleCenters = PossibleCenters; // added by .net follower (http://dotnetfollower.com)
            int size = possibleCenters.Count;

            if (size < 3)
            {
                // Couldn't find enough finder patterns
                throw ReaderException.Instance;
            }

            /*
             * Begin HE modifications to safely detect multiple codes of equal size
             */
            if (size == 3)
            {
                return(new FinderPattern[][] { new FinderPattern[] { (FinderPattern)possibleCenters[0], (FinderPattern)possibleCenters[1], (FinderPattern)possibleCenters[2] } });
            }

            // Sort by estimated module size to speed up the upcoming checks
            Collections.insertionSort(possibleCenters, new ModuleSizeComparator());

            /*
             * Now lets start: build a list of tuples of three finder locations that
             *  - feature similar module sizes
             *  - are placed in a distance so the estimated module count is within the QR specification
             *  - have similar distance between upper left/right and left top/bottom finder patterns
             *  - form a triangle with 90° angle (checked by comparing top right/bottom left distance
             *    with pythagoras)
             *
             * Note: we allow each point to be used for more than one code region: this might seem
             * counterintuitive at first, but the performance penalty is not that big. At this point,
             * we cannot make a good quality decision whether the three finders actually represent
             * a QR code, or are just by chance layouted so it looks like there might be a QR code there.
             * So, if the layout seems right, lets have the decoder try to decode.
             */

            // System.Collections.ArrayList results = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // holder for the results // commented by .net follower (http://dotnetfollower.com)
            System.Collections.Generic.List <Object> results = new System.Collections.Generic.List <Object>(10); // holder for the results // added by .net follower (http://dotnetfollower.com)

            for (int i1 = 0; i1 < (size - 2); i1++)
            {
                FinderPattern p1 = (FinderPattern)possibleCenters[i1];
                if (p1 == null)
                {
                    continue;
                }

                for (int i2 = i1 + 1; i2 < (size - 1); i2++)
                {
                    FinderPattern p2 = (FinderPattern)possibleCenters[i2];
                    if (p2 == null)
                    {
                        continue;
                    }

                    // Compare the expected module sizes; if they are really off, skip
                    float vModSize12  = (p1.EstimatedModuleSize - p2.EstimatedModuleSize) / (System.Math.Min(p1.EstimatedModuleSize, p2.EstimatedModuleSize));
                    float vModSize12A = System.Math.Abs(p1.EstimatedModuleSize - p2.EstimatedModuleSize);
                    if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                    {
                        // break, since elements are ordered by the module size deviation there cannot be
                        // any more interesting elements for the given p1.
                        break;
                    }

                    for (int i3 = i2 + 1; i3 < size; i3++)
                    {
                        FinderPattern p3 = (FinderPattern)possibleCenters[i3];
                        if (p3 == null)
                        {
                            continue;
                        }

                        // Compare the expected module sizes; if they are really off, skip
                        float vModSize23  = (p2.EstimatedModuleSize - p3.EstimatedModuleSize) / (System.Math.Min(p2.EstimatedModuleSize, p3.EstimatedModuleSize));
                        float vModSize23A = System.Math.Abs(p2.EstimatedModuleSize - p3.EstimatedModuleSize);
                        if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT)
                        {
                            // break, since elements are ordered by the module size deviation there cannot be
                            // any more interesting elements for the given p1.
                            break;
                        }

                        FinderPattern[] test = new FinderPattern[] { p1, p2, p3 };
                        ResultPoint.orderBestPatterns(test);

                        // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal
                        FinderPatternInfo info = new FinderPatternInfo(test);
                        float             dA   = ResultPoint.distance(info.TopLeft, info.BottomLeft);
                        float             dC   = ResultPoint.distance(info.TopRight, info.BottomLeft);
                        float             dB   = ResultPoint.distance(info.TopLeft, info.TopRight);

                        // Check the sizes
                        float estimatedModuleCount = ((dA + dB) / p1.EstimatedModuleSize) / 2;
                        if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE || estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE)
                        {
                            continue;
                        }

                        // Calculate the difference of the edge lengths in percent
                        float vABBC = System.Math.Abs(((dA - dB) / System.Math.Min(dA, dB)));
                        if (vABBC >= 0.1f)
                        {
                            continue;
                        }

                        // Calculate the diagonal length by assuming a 90° angle at topleft
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        float dCpy = (float)System.Math.Sqrt(dA * dA + dB * dB);
                        // Compare to the real distance in %
                        float vPyC = System.Math.Abs(((dC - dCpy) / System.Math.Min(dC, dCpy)));

                        if (vPyC >= 0.1f)
                        {
                            continue;
                        }

                        // All tests passed!
                        results.Add(test);
                    }     // end iterate p3
                }         // end iterate p2
            }             // end iterate p1

            if (!(results.Count == 0))
            {
                FinderPattern[][] resultArray = new FinderPattern[results.Count][];
                for (int i = 0; i < results.Count; i++)
                {
                    resultArray[i] = (FinderPattern[])results[i];
                }
                return(resultArray);
            }

            // Nothing found!
            throw ReaderException.Instance;
        }
Exemplo n.º 21
0
        /// <summary> <p>Detects a Data Matrix Code in an image.</p>
        ///
        /// </summary>
        /// <returns> {@link DetectorResult} encapsulating results of detecting a QR Code
        /// </returns>
        /// <throws>  ReaderException if no Data Matrix Code can be found </throws>
        public DetectorResult detect()
        {
            ResultPoint[] cornerPoints = rectangleDetector.detect();
            ResultPoint   pointA       = cornerPoints[0];
            ResultPoint   pointB       = cornerPoints[1];
            ResultPoint   pointC       = cornerPoints[2];
            ResultPoint   pointD       = cornerPoints[3];

            // Point A and D are across the diagonal from one another,
            // as are B and C. Figure out which are the solid black lines
            // by counting transitions
            System.Collections.Generic.List <Object> transitions = new System.Collections.Generic.List <Object>(4); //GregBray: Removed Synchronized wrapper
            transitions.Add(transitionsBetween(pointA, pointB));
            transitions.Add(transitionsBetween(pointA, pointC));
            transitions.Add(transitionsBetween(pointB, pointD));
            transitions.Add(transitionsBetween(pointC, pointD));
            Collections.insertionSort(transitions, new ResultPointsAndTransitionsComparator());

            // Sort by number of transitions. First two will be the two solid sides; last two
            // will be the two alternating black/white sides
            ResultPointsAndTransitions lSideOne = (ResultPointsAndTransitions)transitions[0];
            ResultPointsAndTransitions lSideTwo = (ResultPointsAndTransitions)transitions[1];

            // Figure out which point is their intersection by tallying up the number of times we see the
            // endpoints in the four endpoints. One will show up twice.
            System.Collections.Generic.Dictionary <Object, Object> pointCount = new System.Collections.Generic.Dictionary <Object, Object>();
            increment(pointCount, lSideOne.From);
            increment(pointCount, lSideOne.To);
            increment(pointCount, lSideTwo.From);
            increment(pointCount, lSideTwo.To);

            ResultPoint maybeTopLeft     = null;
            ResultPoint bottomLeft       = null;
            ResultPoint maybeBottomRight = null;

            System.Collections.IEnumerator points = pointCount.Keys.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (points.MoveNext())
            {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                ResultPoint  point         = (ResultPoint)points.Current;
                System.Int32 value_Renamed = (System.Int32)pointCount[point];
                if (value_Renamed == 2)
                {
                    bottomLeft = point;                     // this is definitely the bottom left, then -- end of two L sides
                }
                else
                {
                    // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
                    if (maybeTopLeft == null)
                    {
                        maybeTopLeft = point;
                    }
                    else
                    {
                        maybeBottomRight = point;
                    }
                }
            }

            if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null)
            {
                throw ReaderException.Instance;
            }

            // Bottom left is correct but top left and bottom right might be switched
            ResultPoint[] corners = new ResultPoint[] { maybeTopLeft, bottomLeft, maybeBottomRight };
            // Use the dot product trick to sort them out
            ResultPoint.orderBestPatterns(corners);

            // Now we know which is which:
            ResultPoint bottomRight = corners[0];

            bottomLeft = corners[1];
            ResultPoint topLeft = corners[2];

            // Which point didn't we find in relation to the "L" sides? that's the top right corner
            ResultPoint topRight;

            if (!pointCount.ContainsKey(pointA))
            {
                topRight = pointA;
            }
            else if (!pointCount.ContainsKey(pointB))
            {
                topRight = pointB;
            }
            else if (!pointCount.ContainsKey(pointC))
            {
                topRight = pointC;
            }
            else
            {
                topRight = pointD;
            }

            // Next determine the dimension by tracing along the top or right side and counting black/white
            // transitions. Since we start inside a black module, we should see a number of transitions
            // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
            // end on a black module:

            // The top right point is actually the corner of a module, which is one of the two black modules
            // adjacent to the white module at the top right. Tracing to that corner from either the top left
            // or bottom right should work here. The number of transitions could be higher than it should be
            // due to noise. So we try both and take the min.

            int dimension = System.Math.Min(transitionsBetween(topLeft, topRight).Transitions, transitionsBetween(bottomRight, topRight).Transitions);

            if ((dimension & 0x01) == 1)
            {
                // it can't be odd, so, round... up?
                dimension++;
            }
            dimension += 2;

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

            return(new DetectorResult(bits, new ResultPoint[] { pointA, pointB, pointC, pointD }));
        }
Exemplo n.º 22
0
 /// <summary>
 /// <p>Estimates module size based on two finder patterns -- it uses
 /// <seealso cref="#sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)"/> to figure the
 /// width of each, measuring along the axis between their centers.</p>
 /// </summary>
 private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern)
 {
     float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.X, (int) pattern.Y, (int) otherPattern.X, (int) otherPattern.Y);
     float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.X, (int) otherPattern.Y, (int) pattern.X, (int) pattern.Y);
     if (float.IsNaN(moduleSizeEst1))
     {
       return moduleSizeEst2 / 7.0f;
     }
     if (float.IsNaN(moduleSizeEst2))
     {
       return moduleSizeEst1 / 7.0f;
     }
     // Average them, and divide by 7 since we've counted the width of 3 black modules,
     // and 1 white and 1 black module on either side. Ergo, divide sum by 14.
     return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
 }
Exemplo n.º 23
0
 /// <summary> <p>Computes an average estimated module size based on estimated derived from the positions
 /// of the three finder patterns.</p>
 /// </summary>
 protected internal virtual float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft)
 {
     // Take the average
     return((calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f);
 }
Exemplo n.º 24
0
        /// <summary>
        /// Because we scan horizontally to detect the start and stop patterns, the vertical component of
        /// the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.
        /// This method moves those points back onto the edges of the theoretically perfect bounding
        /// quadrilateral if needed.
        /// </summary>
        /// <param name="vertices"> The eight vertices located by findVertices(). </param>
        private static void correctCodeWordVertices(ResultPoint[] vertices, bool upsideDown)
        {
            float v0x = vertices[0].X;
            float v0y = vertices[0].Y;
            float v2x = vertices[2].X;
            float v2y = vertices[2].Y;
            float v4x = vertices[4].X;
            float v4y = vertices[4].Y;
            float v6x = vertices[6].X;
            float v6y = vertices[6].Y;

            float skew = v4y - v6y;
            if (upsideDown)
            {
              skew = -skew;
            }
            if (skew > SKEW_THRESHOLD)
            {
              // Fix v4
              float deltax = v6x - v0x;
              float deltay = v6y - v0y;
              float delta2 = deltax * deltax + deltay * deltay;
              float correction = (v4x - v0x) * deltax / delta2;
              vertices[4] = new ResultPoint(v0x + correction * deltax, v0y + correction * deltay);
            }
            else if (-skew > SKEW_THRESHOLD)
            {
              // Fix v6
              float deltax = v2x - v4x;
              float deltay = v2y - v4y;
              float delta2 = deltax * deltax + deltay * deltay;
              float correction = (v2x - v6x) * deltax / delta2;
              vertices[6] = new ResultPoint(v2x - correction * deltax, v2y - correction * deltay);
            }

            float v1x = vertices[1].X;
            float v1y = vertices[1].Y;
            float v3x = vertices[3].X;
            float v3y = vertices[3].Y;
            float v5x = vertices[5].X;
            float v5y = vertices[5].Y;
            float v7x = vertices[7].X;
            float v7y = vertices[7].Y;

            skew = v7y - v5y;
            if (upsideDown)
            {
              skew = -skew;
            }
            if (skew > SKEW_THRESHOLD)
            {
              // Fix v5
              float deltax = v7x - v1x;
              float deltay = v7y - v1y;
              float delta2 = deltax * deltax + deltay * deltay;
              float correction = (v5x - v1x) * deltax / delta2;
              vertices[5] = new ResultPoint(v1x + correction * deltax, v1y + correction * deltay);
            }
            else if (-skew > SKEW_THRESHOLD)
            {
              // Fix v7
              float deltax = v3x - v5x;
              float deltay = v3y - v5y;
              float delta2 = deltax * deltax + deltay * deltay;
              float correction = (v3x - v7x) * deltax / delta2;
              vertices[7] = new ResultPoint(v3x - correction * deltax, v3y - correction * deltay);
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Locate the vertices and the codewords area of a black blob using the Start
        /// and Stop patterns as locators. This assumes that the image is rotated 180
        /// degrees and if it locates the start and stop patterns at it will re-map
        /// the vertices for a 0 degree rotation.
        /// TODO: Change assumption about barcode location.
        /// </summary>
        /// <param name="matrix"> the scanned barcode image. </param>
        /// <returns> an array containing the vertices:
        ///           vertices[0] x, y top left barcode
        ///           vertices[1] x, y bottom left barcode
        ///           vertices[2] x, y top right barcode
        ///           vertices[3] x, y bottom right barcode
        ///           vertices[4] x, y top left codeword area
        ///           vertices[5] x, y bottom left codeword area
        ///           vertices[6] x, y top right codeword area
        ///           vertices[7] x, y bottom right codeword area </returns>
        private static ResultPoint[] findVertices180(BitMatrix matrix, bool tryHarder)
        {
            int height = matrix.Height;
            int width = matrix.Width;
            int halfWidth = width >> 1;

            ResultPoint[] result = new ResultPoint[8];
            bool found = false;

            int[] counters = new int[START_PATTERN_REVERSE.Length];

            int rowStep = Math.Max(1, height >> (tryHarder ? 9 : 7));

            // Top Left
            for (int i = height - 1; i > 0; i -= rowStep)
            {
              int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE, counters);
              if (loc != null)
              {
            result[0] = new ResultPoint(loc[1], i);
            result[4] = new ResultPoint(loc[0], i);
            found = true;
            break;
              }
            }
            // Bottom Left
            if (found) // Found the Top Left vertex
            {
              found = false;
              for (int i = 0; i < height; i += rowStep)
              {
            int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE, counters);
            if (loc != null)
            {
              result[1] = new ResultPoint(loc[1], i);
              result[5] = new ResultPoint(loc[0], i);
              found = true;
              break;
            }
              }
            }

            counters = new int[STOP_PATTERN_REVERSE.Length];

            // Top Right
            if (found) // Found the Bottom Left vertex
            {
              found = false;
              for (int i = height - 1; i > 0; i -= rowStep)
              {
            int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE, counters);
            if (loc != null)
            {
              result[2] = new ResultPoint(loc[0], i);
              result[6] = new ResultPoint(loc[1], i);
              found = true;
              break;
            }
              }
            }
            // Bottom Right
            if (found) // Found the Top Right vertex
            {
              found = false;
              for (int i = 0; i < height; i += rowStep)
              {
            int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE, counters);
            if (loc != null)
            {
              result[3] = new ResultPoint(loc[0], i);
              result[7] = new ResultPoint(loc[1], i);
              found = true;
              break;
            }
              }
            }
            return found ? result : null;
        }
Exemplo n.º 26
0
 /// <summary>
 /// Computes the y dimension (number of modules in a column) of the PDF417 Code
 /// based on vertices of the codeword area and estimated module size.
 /// </summary>
 /// <param name="topLeft">     of codeword area </param>
 /// <param name="topRight">    of codeword area </param>
 /// <param name="bottomLeft">  of codeword area </param>
 /// <param name="bottomRight"> of codeword are </param>
 /// <param name="moduleWidth"> estimated module size </param>
 /// <returns> the number of modules in a row. </returns>
 private static int computeYDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth)
 {
     int leftColumnDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleWidth);
     int rightColumnDimension = MathUtils.round(ResultPoint.distance(topRight, bottomRight) / moduleWidth);
     return (leftColumnDimension + rightColumnDimension) >> 1;
 }
Exemplo n.º 27
0
 /// <summary>
 /// Computes the dimension (number of modules in a row) of the PDF417 Code
 /// based on vertices of the codeword area and estimated module size.
 /// </summary>
 /// <param name="topLeft">     of codeword area </param>
 /// <param name="topRight">    of codeword area </param>
 /// <param name="bottomLeft">  of codeword area </param>
 /// <param name="bottomRight"> of codeword are </param>
 /// <param name="moduleWidth"> estimated module size </param>
 /// <returns> the number of modules in a row. </returns>
 private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth)
 {
     int topRowDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleWidth);
     int bottomRowDimension = MathUtils.round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth);
     return ((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17;
 }
Exemplo n.º 28
0
			internal ResultPointsAndTransitions(ResultPoint from, ResultPoint to, int transitions)
			{
				this.from = from;
				this.to = to;
				this.transitions = transitions;
			}
Exemplo n.º 29
0
        public virtual PerspectiveTransform createTransform(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint alignmentPattern, int dimension)
        {
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float dimMinusThree = (float) dimension - 3.5f;
            float bottomRightX;
            float bottomRightY;
            float sourceBottomRightX;
            float sourceBottomRightY;
            if (alignmentPattern != null)
            {
                bottomRightX = alignmentPattern.X;
                bottomRightY = alignmentPattern.Y;
                sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
            }
            else
            {
                // Don't have an alignment pattern, just make up the bottom-right point
                bottomRightX = (topRight.X - topLeft.X) + bottomLeft.X;
                bottomRightY = (topRight.Y - topLeft.Y) + bottomLeft.Y;
                sourceBottomRightX = sourceBottomRightY = dimMinusThree;
            }

            PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, topLeft.X, topLeft.Y, topRight.X, topRight.Y, bottomRightX, bottomRightY, bottomLeft.X, bottomLeft.Y);

            return transform;
        }
Exemplo n.º 30
0
		/// <summary> Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.</summary>
		private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to)
		{
			// See QR Code Detector, sizeOfBlackWhiteBlackRun()
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			int fromX = (int) from.X;
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			int fromY = (int) from.Y;
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			int toX = (int) to.X;
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			int toY = (int) to.Y;
			bool steep = System.Math.Abs(toY - fromY) > System.Math.Abs(toX - fromX);
			if (steep)
			{
				int temp = fromX;
				fromX = fromY;
				fromY = temp;
				temp = toX;
				toX = toY;
				toY = temp;
			}
			
			int dx = System.Math.Abs(toX - fromX);
			int dy = System.Math.Abs(toY - fromY);
			int error = - dx >> 1;
			int ystep = fromY < toY?1:- 1;
			int xstep = fromX < toX?1:- 1;
			int transitions = 0;
			bool inBlack = image.get_Renamed(steep?fromY:fromX, steep?fromX:fromY);
			for (int x = fromX, y = fromY; x != toX; x += xstep)
			{
				bool isBlack = image.get_Renamed(steep?y:x, steep?x:y);
				if (isBlack != inBlack)
				{
					transitions++;
					inBlack = isBlack;
				}
				error += dy;
				if (error > 0)
				{
					if (y == toY)
					{
						break;
					}
					y += ystep;
					error -= dx;
				}
			}
			return new ResultPointsAndTransitions(from, to, transitions);
		}
Exemplo n.º 31
0
 /// <summary>
 /// <p>Computes the dimension (number of modules on a size) of the QR Code based on the position
 /// of the finder patterns and estimated module size.</p>
 /// </summary>
 //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
 //ORIGINAL LINE: private static int computeDimension(com.google.zxing.ResultPoint topLeft, com.google.zxing.ResultPoint topRight, com.google.zxing.ResultPoint bottomLeft, float moduleSize) throws com.google.zxing.NotFoundException
 private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize)
 {
     int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize);
     int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
     int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
     switch (dimension & 0x03) // mod 4
     {
       case 0:
     dimension++;
     break;
     // 1? do nothing
       case 2:
     dimension--;
     break;
       case 3:
     throw NotFoundException.NotFoundInstance;
     }
     return dimension;
 }
Exemplo n.º 32
0
		private static BitMatrix sampleGrid(BitMatrix 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.X - bottomLeft.X) + topLeft.X;
			float topRightY = (bottomRight.Y - bottomLeft.Y) + topLeft.Y;
			
			// 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.X, topLeft.Y, topRightX, topRightY, bottomRight.X, bottomRight.Y, bottomLeft.X, bottomLeft.Y);
		}
Exemplo n.º 33
0
		/// <summary> <p>Detects a Data Matrix Code in an image.</p>
		/// 
		/// </summary>
		/// <returns> {@link DetectorResult} encapsulating results of detecting a QR Code
		/// </returns>
		/// <throws>  ReaderException if no Data Matrix Code can be found </throws>
		public DetectorResult detect()
		{
			
			ResultPoint[] cornerPoints = rectangleDetector.detect();
			ResultPoint pointA = cornerPoints[0];
			ResultPoint pointB = cornerPoints[1];
			ResultPoint pointC = cornerPoints[2];
			ResultPoint pointD = cornerPoints[3];
			
			// Point A and D are across the diagonal from one another,
			// as are B and C. Figure out which are the solid black lines
			// by counting transitions
			System.Collections.ArrayList transitions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(4));
			transitions.Add(transitionsBetween(pointA, pointB));
			transitions.Add(transitionsBetween(pointA, pointC));
			transitions.Add(transitionsBetween(pointB, pointD));
			transitions.Add(transitionsBetween(pointC, pointD));
			Collections.insertionSort(transitions, new ResultPointsAndTransitionsComparator());
			
			// Sort by number of transitions. First two will be the two solid sides; last two
			// will be the two alternating black/white sides
			ResultPointsAndTransitions lSideOne = (ResultPointsAndTransitions) transitions[0];
			ResultPointsAndTransitions lSideTwo = (ResultPointsAndTransitions) transitions[1];
			
			// Figure out which point is their intersection by tallying up the number of times we see the
			// endpoints in the four endpoints. One will show up twice.
			System.Collections.Hashtable pointCount = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
			increment(pointCount, lSideOne.From);
			increment(pointCount, lSideOne.To);
			increment(pointCount, lSideTwo.From);
			increment(pointCount, lSideTwo.To);
			
			ResultPoint maybeTopLeft = null;
			ResultPoint bottomLeft = null;
			ResultPoint maybeBottomRight = null;
			System.Collections.IEnumerator points = pointCount.Keys.GetEnumerator();
			//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
			while (points.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
				ResultPoint point = (ResultPoint) points.Current;
				System.Int32 value_Renamed = (System.Int32) pointCount[point];
				if (value_Renamed == 2)
				{
					bottomLeft = point; // this is definitely the bottom left, then -- end of two L sides
				}
				else
				{
					// Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
					if (maybeTopLeft == null)
					{
						maybeTopLeft = point;
					}
					else
					{
						maybeBottomRight = point;
					}
				}
			}
			
			if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null)
			{
				throw ReaderException.Instance;
			}
			
			// Bottom left is correct but top left and bottom right might be switched
			ResultPoint[] corners = new ResultPoint[]{maybeTopLeft, bottomLeft, maybeBottomRight};
			// Use the dot product trick to sort them out
			ResultPoint.orderBestPatterns(corners);
			
			// Now we know which is which:
			ResultPoint bottomRight = corners[0];
			bottomLeft = corners[1];
			ResultPoint topLeft = corners[2];
			
			// Which point didn't we find in relation to the "L" sides? that's the top right corner
			ResultPoint topRight;
			if (!pointCount.ContainsKey(pointA))
			{
				topRight = pointA;
			}
			else if (!pointCount.ContainsKey(pointB))
			{
				topRight = pointB;
			}
			else if (!pointCount.ContainsKey(pointC))
			{
				topRight = pointC;
			}
			else
			{
				topRight = pointD;
			}
			
			// Next determine the dimension by tracing along the top or right side and counting black/white
			// transitions. Since we start inside a black module, we should see a number of transitions
			// equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
			// end on a black module:
			
			// The top right point is actually the corner of a module, which is one of the two black modules
			// adjacent to the white module at the top right. Tracing to that corner from either the top left
			// or bottom right should work here. The number of transitions could be higher than it should be
			// due to noise. So we try both and take the min.
			
			int dimension = System.Math.Min(transitionsBetween(topLeft, topRight).Transitions, transitionsBetween(bottomRight, topRight).Transitions);
			if ((dimension & 0x01) == 1)
			{
				// it can't be odd, so, round... up?
				dimension++;
			}
			dimension += 2;
			
			BitMatrix bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, dimension);
			return new DetectorResult(bits, new ResultPoint[]{pointA, pointB, pointC, pointD});
		}
Exemplo n.º 34
0
 public DetectorResult(BitMatrix bits, ResultPoint[] points)
 {
     this.bits = bits;
     this.points = points;
 }
Exemplo n.º 35
0
 internal ResultPointsAndTransitions(ResultPoint from, ResultPoint to, int transitions)
 {
     this.from        = from;
     this.to          = to;
     this.transitions = transitions;
 }
Exemplo n.º 36
0
        protected internal virtual DetectorResult processFinderPatternInfo(FinderPatternInfo info)
        {
            FinderPattern topLeft    = info.TopLeft;
            FinderPattern topRight   = info.TopRight;
            FinderPattern bottomLeft = info.BottomLeft;

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

            if (moduleSize < 1.0f)
            {
                throw ReaderException.Instance;
            }
            int     dimension               = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
            Version provisionalVersion      = Version.getProvisionalVersionForDimension(dimension);
            int     modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7;

            AlignmentPattern alignmentPattern = null;

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

                // Estimate that alignment pattern is closer by 3 modules
                // from "bottom right" to known top left location
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                int estAlignmentX = (int)(topLeft.X + correctionToTopLeft * (bottomRightX - topLeft.X));
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                int estAlignmentY = (int)(topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y));

                // Kind of arbitrary -- expand search radius before giving up
                for (int i = 4; i <= 16; i <<= 1)
                {
                    try
                    {
                        //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                        alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
                        break;
                    }
                    catch (ReaderException re)
                    {
                        // try next round
                    }
                }
                // If we didn't find alignment pattern... well try anyway without it
            }

            PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            BitMatrix bits = sampleGrid(image, transform, 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));
        }
Exemplo n.º 37
0
        /// <summary> 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".
        ///
        /// </summary>
        /// <param name="image">The image to decode
        /// </param>
        /// <param name="hints">Any hints that were requested
        /// </param>
        /// <returns> The contents of the decoded barcode
        /// </returns>
        /// <throws>  ReaderException Any spontaneous errors which occur </throws>
        private Result doDecode(BinaryBitmap image, Dictionary <object, object> hints)
        {
            int      width  = image.Width;
            int      height = image.Height;
            BitArray row    = new BitArray(width);

            int  middle    = height >> 1;
            bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
            int  rowStep   = System.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
                {
                    row = image.getBlackRow(rowNumber, row);
                }
                catch (ReaderException)
                {
                    continue;
                }

                // 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
                        // This means we will only ever draw result points *once* in the life of this method
                        // since we want to avoid drawing the wrong points after flipping the row, and,
                        // don't want to clutter with noise from every single row scan -- just the scans
                        // that start on the center line.
                        if (hints != null && hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
                        {
                            Dictionary <object, object>    newHints = new Dictionary <object, object>();
                            System.Collections.IEnumerator hintEnum = hints.Keys.GetEnumerator();
                            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                            while (hintEnum.MoveNext())
                            {
                                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                                System.Object key = hintEnum.Current;
                                if (!key.Equals(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
                                {
                                    newHints[key] = hints[key];
                                }
                            }
                            hints = newHints;
                        }
                    }
                    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, (System.Object) 180);
                            // And remember to flip the result points horizontally.
                            ResultPoint[] points = result.ResultPoints;
                            points[0] = new ResultPoint(width - points[0].X - 1, points[0].Y);
                            points[1] = new ResultPoint(width - points[1].X - 1, points[1].Y);
                        }
                        return(result);
                    }
                    catch (ReaderException)
                    {
                        // continue -- just couldn't decode this row
                    }
                }
            }

            throw ReaderException.Instance;
        }
Exemplo n.º 38
0
 // Note that we don't try rotation without the try harder flag, even if rotation was supported.
 //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
 //ORIGINAL LINE: public com.google.zxing.Result decode(com.google.zxing.BinaryBitmap image, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.NotFoundException, com.google.zxing.FormatException
 public virtual Result decode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
 {
     try
     {
       return doDecode(image, hints);
     }
     catch (NotFoundException nfe)
     {
       bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
       if (tryHarder && image.RotateSupported)
       {
     BinaryBitmap rotatedImage = image.rotateCounterClockwise();
     Result result = doDecode(rotatedImage, hints);
     // Record that we found it rotated 90 degrees CCW / 270 degrees CW
     //JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET:
     //ORIGINAL LINE: java.util.Map<com.google.zxing.ResultMetadataType,?> metadata = result.getResultMetadata();
     IDictionary<ResultMetadataType, object> metadata = result.ResultMetadata;
     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);
     // Update result points
     ResultPoint[] points = result.ResultPoints;
     if (points != null)
     {
       int height = rotatedImage.Height;
       for (int i = 0; i < points.Length; i++)
       {
         points[i] = new ResultPoint(height - points[i].Y - 1, points[i].X);
       }
     }
     return result;
       }
       else
       {
     throw nfe;
       }
     }
 }
Exemplo n.º 39
0
        // public FinderPatternInfo[] findMulti(System.Collections.Hashtable hints) // commented by .net follower (http://dotnetfollower.com)
        public FinderPatternInfo[] findMulti(System.Collections.Generic.Dictionary <Object, Object> hints) // added by .net follower (http://dotnetfollower.com)
        {
            bool      tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
            BitMatrix image     = Image;
            int       maxI      = image.Height;
            int       maxJ      = image.Width;
            // We are looking for black/white/black/white/black modules in
            // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far

            // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
            // image, and then account for the center being 3 modules in size. This gives the smallest
            // number of pixels the center could be, so skip this often. When trying harder, look for all
            // QR versions regardless of how dense they are.
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int iSkip = (int)(maxI / (MAX_MODULES * 4.0f) * 3);

            if (iSkip < MIN_SKIP || tryHarder)
            {
                iSkip = MIN_SKIP;
            }

            int[] stateCount = new int[5];
            for (int i = iSkip - 1; i < maxI; i += iSkip)
            {
                // Get a row of black/white values
                stateCount[0] = 0;
                stateCount[1] = 0;
                stateCount[2] = 0;
                stateCount[3] = 0;
                stateCount[4] = 0;
                int currentState = 0;
                for (int j = 0; j < maxJ; j++)
                {
                    if (image.get_Renamed(j, i))
                    {
                        // Black pixel
                        if ((currentState & 1) == 1)
                        {
                            // Counting white pixels
                            currentState++;
                        }
                        stateCount[currentState]++;
                    }
                    else
                    {
                        // White pixel
                        if ((currentState & 1) == 0)
                        {
                            // Counting black pixels
                            if (currentState == 4)
                            {
                                // A winner?
                                if (foundPatternCross(stateCount))
                                {
                                    // Yes
                                    bool confirmed = handlePossibleCenter(stateCount, i, j);
                                    if (!confirmed)
                                    {
                                        do
                                        {
                                            // Advance to next black pixel
                                            j++;
                                        }while (j < maxJ && !image.get_Renamed(j, i));
                                        j--;                                         // back up to that last white pixel
                                    }
                                    // Clear state to start looking again
                                    currentState  = 0;
                                    stateCount[0] = 0;
                                    stateCount[1] = 0;
                                    stateCount[2] = 0;
                                    stateCount[3] = 0;
                                    stateCount[4] = 0;
                                }
                                else
                                {
                                    // No, shift counts back by two
                                    stateCount[0] = stateCount[2];
                                    stateCount[1] = stateCount[3];
                                    stateCount[2] = stateCount[4];
                                    stateCount[3] = 1;
                                    stateCount[4] = 0;
                                    currentState  = 3;
                                }
                            }
                            else
                            {
                                stateCount[++currentState]++;
                            }
                        }
                        else
                        {
                            // Counting white pixels
                            stateCount[currentState]++;
                        }
                    }
                }                 // for j=...

                if (foundPatternCross(stateCount))
                {
                    handlePossibleCenter(stateCount, i, maxJ);
                }         // end if foundPatternCross
            }             // for i=iSkip-1 ...
            FinderPattern[][] patternInfo = selectBestPatterns();
            // System.Collections.ArrayList result = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); // commented by .net follower (http://dotnetfollower.com)
            System.Collections.Generic.List <Object> result = new System.Collections.Generic.List <Object>(10); // added by .net follower (http://dotnetfollower.com)
            for (int i = 0; i < patternInfo.Length; i++)
            {
                FinderPattern[] pattern = patternInfo[i];
                ResultPoint.orderBestPatterns(pattern);
                result.Add(new FinderPatternInfo(pattern));
            }

            if ((result.Count == 0))
            {
                return(EMPTY_RESULT_ARRAY);
            }
            else
            {
                FinderPatternInfo[] resultArray = new FinderPatternInfo[result.Count];
                for (int i = 0; i < result.Count; i++)
                {
                    resultArray[i] = (FinderPatternInfo)result[i];
                }
                return(resultArray);
            }
        }
Exemplo n.º 40
0
		/// <summary> Locate the vertices and the codewords area of a black blob using the Start
		/// and Stop patterns as locators. This assumes that the image is rotated 180
		/// degrees and if it locates the start and stop patterns at it will re-map
		/// the vertices for a 0 degree rotation.
		/// TODO: Change assumption about barcode location.
		/// TODO: Scanning every row is very expensive. We should only do this for TRY_HARDER.
		/// 
		/// </summary>
		/// <param name="matrix">the scanned barcode image.
		/// </param>
		/// <returns> an array containing the vertices:
		/// vertices[0] x, y top left barcode
		/// vertices[1] x, y bottom left barcode
		/// vertices[2] x, y top right barcode
		/// vertices[3] x, y bottom right barcode
		/// vertices[4] x, y top left codeword area
		/// vertices[5] x, y bottom left codeword area
		/// vertices[6] x, y top right codeword area
		/// vertices[7] x, y bottom right codeword area
		/// </returns>
		private static ResultPoint[] findVertices180(BitMatrix matrix)
		{
			int height = matrix.Height;
			int width = matrix.Width;
			int halfWidth = width >> 1;
			
			ResultPoint[] result = new ResultPoint[8];
			bool found = false;
			
			// Top Left
			for (int i = height - 1; i > 0; i--)
			{
				int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
				if (loc != null)
				{
					result[0] = new ResultPoint(loc[1], i);
					result[4] = new ResultPoint(loc[0], i);
					found = true;
					break;
				}
			}
			// Bottom Left
			if (found)
			{
				// Found the Top Left vertex
				found = false;
				for (int i = 0; i < height; i++)
				{
					int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
					if (loc != null)
					{
						result[1] = new ResultPoint(loc[1], i);
						result[5] = new ResultPoint(loc[0], i);
						found = true;
						break;
					}
				}
			}
			// Top Right
			if (found)
			{
				// Found the Bottom Left vertex
				found = false;
				for (int i = height - 1; i > 0; i--)
				{
					int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
					if (loc != null)
					{
						result[2] = new ResultPoint(loc[0], i);
						result[6] = new ResultPoint(loc[1], i);
						found = true;
						break;
					}
				}
			}
			// Bottom Right
			if (found)
			{
				// Found the Top Right vertex
				found = false;
				for (int i = 0; i < height; i++)
				{
					int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
					if (loc != null)
					{
						result[3] = new ResultPoint(loc[0], i);
						result[7] = new ResultPoint(loc[1], i);
						found = true;
						break;
					}
				}
			}
			return found?result:null;
		}
Exemplo n.º 41
0
        private void  doDecodeMultiple(BinaryBitmap image, System.Collections.Hashtable hints, System.Collections.ArrayList results, int xOffset, int yOffset)
        {
            Result result;

            try
            {
                result = delegate_Renamed.decode(image, hints);
            }
            catch (ReaderException)
            {
                return;
            }
            bool alreadyFound = false;

            for (int i = 0; i < results.Count; i++)
            {
                Result existingResult = (Result)results[i];
                if (existingResult.Text.Equals(result.Text))
                {
                    alreadyFound = true;
                    break;
                }
            }
            if (alreadyFound)
            {
                return;
            }
            results.Add(translateResultPoints(result, xOffset, yOffset));
            ResultPoint[] resultPoints = result.ResultPoints;
            if (resultPoints == null || resultPoints.Length == 0)
            {
                return;
            }
            int   width  = image.Width;
            int   height = image.Height;
            float minX   = width;
            float minY   = height;
            float maxX   = 0.0f;
            float maxY   = 0.0f;

            for (int i = 0; i < resultPoints.Length; i++)
            {
                ResultPoint point = resultPoints[i];
                float       x     = point.X;
                float       y     = point.Y;
                if (x < minX)
                {
                    minX = x;
                }
                if (y < minY)
                {
                    minY = y;
                }
                if (x > maxX)
                {
                    maxX = x;
                }
                if (y > maxY)
                {
                    maxY = y;
                }
            }

            // Decode left of barcode
            if (minX > MIN_DIMENSION_TO_RECUR)
            {
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                doDecodeMultiple(image.crop(0, 0, (int)minX, height), hints, results, xOffset, yOffset);
            }
            // Decode above barcode
            if (minY > MIN_DIMENSION_TO_RECUR)
            {
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                doDecodeMultiple(image.crop(0, 0, width, (int)minY), hints, results, xOffset, yOffset);
            }
            // Decode right of barcode
            if (maxX < width - MIN_DIMENSION_TO_RECUR)
            {
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                doDecodeMultiple(image.crop((int)maxX, 0, width - (int)maxX, height), hints, results, xOffset + (int)maxX, yOffset);
            }
            // Decode below barcode
            if (maxY < height - MIN_DIMENSION_TO_RECUR)
            {
                //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
                doDecodeMultiple(image.crop(0, (int)maxY, width, height - (int)maxY), hints, results, xOffset, yOffset + (int)maxY);
            }
        }
Exemplo n.º 42
0
		/// <summary> Because we scan horizontally to detect the start and stop patterns, the vertical component of
		/// the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.
		/// This method moves those points back onto the edges of the theoretically perfect bounding
		/// quadrilateral if needed.
		/// 
		/// </summary>
		/// <param name="vertices">The eight vertices located by findVertices().
		/// </param>
		private static void  correctCodeWordVertices(ResultPoint[] vertices, bool upsideDown)
		{
			float skew = vertices[4].Y - vertices[6].Y;
			if (upsideDown)
			{
				skew = - skew;
			}
			if (skew > SKEW_THRESHOLD)
			{
				// Fix v4
				float length = vertices[4].X - vertices[0].X;
				float deltax = vertices[6].X - vertices[0].X;
				float deltay = vertices[6].Y - vertices[0].Y;
				float correction = length * deltay / deltax;
				vertices[4] = new ResultPoint(vertices[4].X, vertices[4].Y + correction);
			}
			else if (- skew > SKEW_THRESHOLD)
			{
				// Fix v6
				float length = vertices[2].X - vertices[6].X;
				float deltax = vertices[2].X - vertices[4].X;
				float deltay = vertices[2].Y - vertices[4].Y;
				float correction = length * deltay / deltax;
				vertices[6] = new ResultPoint(vertices[6].X, vertices[6].Y - correction);
			}
			
			skew = vertices[7].Y - vertices[5].Y;
			if (upsideDown)
			{
				skew = - skew;
			}
			if (skew > SKEW_THRESHOLD)
			{
				// Fix v5
				float length = vertices[5].X - vertices[1].X;
				float deltax = vertices[7].X - vertices[1].X;
				float deltay = vertices[7].Y - vertices[1].Y;
				float correction = length * deltay / deltax;
				vertices[5] = new ResultPoint(vertices[5].X, vertices[5].Y + correction);
			}
			else if (- skew > SKEW_THRESHOLD)
			{
				// Fix v7
				float length = vertices[3].X - vertices[7].X;
				float deltax = vertices[3].X - vertices[5].X;
				float deltay = vertices[3].Y - vertices[5].Y;
				float correction = length * deltay / deltax;
				vertices[7] = new ResultPoint(vertices[7].X, vertices[7].Y - correction);
			}
		}
Exemplo n.º 43
0
 /// <summary> <p>Computes an average estimated module size based on estimated derived from the positions
 /// of the three finder patterns.</p>
 /// </summary>
 protected internal virtual float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft)
 {
     // Take the average
     return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
 }
Exemplo n.º 44
0
		/// <summary> <p>Estimates module size (pixels in a module) based on the Start and End
		/// finder patterns.</p>
		/// 
		/// </summary>
		/// <param name="vertices">an array of vertices:
		/// vertices[0] x, y top left barcode
		/// vertices[1] x, y bottom left barcode
		/// vertices[2] x, y top right barcode
		/// vertices[3] x, y bottom right barcode
		/// vertices[4] x, y top left codeword area
		/// vertices[5] x, y bottom left codeword area
		/// vertices[6] x, y top right codeword area
		/// vertices[7] x, y bottom right codeword area
		/// </param>
		/// <returns> the module size.
		/// </returns>
		private static float computeModuleWidth(ResultPoint[] vertices)
		{
			float pixels1 = ResultPoint.distance(vertices[0], vertices[4]);
			float pixels2 = ResultPoint.distance(vertices[1], vertices[5]);
			float moduleWidth1 = (pixels1 + pixels2) / (17 * 2.0f);
			float pixels3 = ResultPoint.distance(vertices[6], vertices[2]);
			float pixels4 = ResultPoint.distance(vertices[7], vertices[3]);
			float moduleWidth2 = (pixels3 + pixels4) / (18 * 2.0f);
			return (moduleWidth1 + moduleWidth2) / 2.0f;
		}
Exemplo n.º 45
0
 /// <summary> <p>Estimates module size based on two finder patterns -- it uses
 /// {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
 /// width of each, measuring along the axis between their centers.</p>
 /// </summary>
 private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern)
 {
     //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
     float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.X, (int) pattern.Y, (int) otherPattern.X, (int) otherPattern.Y);
     //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
     float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.X, (int) otherPattern.Y, (int) pattern.X, (int) pattern.Y);
     if (System.Single.IsNaN(moduleSizeEst1))
     {
         return moduleSizeEst2 / 7.0f;
     }
     if (System.Single.IsNaN(moduleSizeEst2))
     {
         return moduleSizeEst1 / 7.0f;
     }
     // Average them, and divide by 7 since we've counted the width of 3 black modules,
     // and 1 white and 1 black module on either side. Ergo, divide sum by 14.
     return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
 }
Exemplo n.º 46
0
		/// <summary> Computes the dimension (number of modules in a row) of the PDF417 Code
		/// based on vertices of the codeword area and estimated module size.
		/// 
		/// </summary>
		/// <param name="topLeft">    of codeword area
		/// </param>
		/// <param name="topRight">   of codeword area
		/// </param>
		/// <param name="bottomLeft"> of codeword area
		/// </param>
		/// <param name="bottomRight">of codeword are
		/// </param>
		/// <param name="moduleWidth">estimated module size
		/// </param>
		/// <returns> the number of modules in a row.
		/// </returns>
		private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth)
		{
			int topRowDimension = round(ResultPoint.distance(topLeft, topRight) / moduleWidth);
			int bottomRowDimension = round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth);
			return ((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17;
			/*
			* int topRowDimension = round(ResultPoint.distance(topLeft,
			* topRight)); //moduleWidth); int bottomRowDimension =
			* round(ResultPoint.distance(bottomLeft, bottomRight)); //
			* moduleWidth); int dimension = ((topRowDimension + bottomRowDimension)
			* >> 1); // Round up to nearest 17 modules i.e. there are 17 modules per
			* codeword //int dimension = ((((topRowDimension + bottomRowDimension) >>
			* 1) + 8) / 17) * 17; return dimension;
			*/
		}
 private static Result translateResultPoints(Result result, int xOffset, int yOffset)
 {
     ResultPoint[] oldResultPoints = result.ResultPoints;
     ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.Length];
     for (int i = 0; i < oldResultPoints.Length; i++)
     {
         ResultPoint oldPoint = oldResultPoints[i];
         newResultPoints[i] = new ResultPoint(oldPoint.X + xOffset, oldPoint.Y + yOffset);
     }
     return new Result(result.Text, result.RawBytes, newResultPoints, result.BarcodeFormat);
 }
Exemplo n.º 48
0
		private static BitMatrix sampleGrid(BitMatrix matrix, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight, int dimension)
		{
			
			// Note that unlike 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(matrix, dimension, 0.0f, 0.0f, dimension, 0.0f, dimension, dimension, 0.0f, dimension, topLeft.X, topLeft.Y, topRight.X, topRight.Y, bottomRight.X, bottomRight.Y, bottomLeft.X, bottomLeft.Y); // p4FromY
		}
Exemplo n.º 49
0
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: protected final com.google.zxing.common.DetectorResult processFinderPatternInfo(FinderPatternInfo info) throws com.google.zxing.NotFoundException, com.google.zxing.FormatException
        protected internal DetectorResult processFinderPatternInfo(FinderPatternInfo info)
        {
            FinderPattern topLeft = info.TopLeft;
            FinderPattern topRight = info.TopRight;
            FinderPattern bottomLeft = info.BottomLeft;

            float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
            if (moduleSize < 1.0f)
            {
              throw NotFoundException.NotFoundInstance;
            }
            int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
            Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
            int modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7;

            AlignmentPattern alignmentPattern = null;
            // Anything above version 1 has an alignment pattern
            if (provisionalVersion.AlignmentPatternCenters.Length > 0)
            {

              // Guess where a "bottom right" finder pattern would have been
              float bottomRightX = topRight.X - topLeft.X + bottomLeft.X;
              float bottomRightY = topRight.Y - topLeft.Y + bottomLeft.Y;

              // 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.X + correctionToTopLeft * (bottomRightX - topLeft.X));
              int estAlignmentY = (int)(topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y));

              // 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 (NotFoundException re)
            {
              // try next round
            }
              }
              // If we didn't find alignment pattern... well try anyway without it
            }

            PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            BitMatrix bits = sampleGrid(image, transform, 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);
        }
Exemplo n.º 50
0
		/// <summary> Increments the Integer associated with a key by one.</summary>
		private static void  increment(System.Collections.Hashtable table, ResultPoint key)
		{
            //System.Int32 value_Renamed = (System.Int32) table[key];
            ////UPGRADE_TODO: The 'System.Int32' structure does not have an equivalent to NULL. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1291'"
            //table[key] = value_Renamed == null?INTEGERS[1]:INTEGERS[value_Renamed + 1];
            // Redivivus.in Java to c# Porting update
            // 30/01/2010 
            // Added
            // START
            System.Int32 value_Renamed = 0;
            try
            {
                if (table.Count > 0)
                    value_Renamed = (System.Int32)table[key];
            }
            catch
            {
                value_Renamed = 0;
            }
            table[key] = value_Renamed == 0 ? INTEGERS[1] : INTEGERS[value_Renamed + 1];
            //END
		}
Exemplo n.º 51
0
		/// <summary> 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".
		/// 
		/// </summary>
		/// <param name="image">The image to decode
		/// </param>
		/// <param name="hints">Any hints that were requested
		/// </param>
		/// <returns> The contents of the decoded barcode
		/// </returns>
		/// <throws>  ReaderException Any spontaneous errors which occur </throws>
		private Result doDecode(BinaryBitmap image, System.Collections.Hashtable hints)
		{
			int width = image.Width;
			int height = image.Height;
			BitArray row = new BitArray(width);
			
			int middle = height >> 1;
			bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
			int rowStep = System.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
				{
					row = image.getBlackRow(rowNumber, row);
				}
				catch (ReaderException)
				{
					continue;
				}
				
				// 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
						// This means we will only ever draw result points *once* in the life of this method
						// since we want to avoid drawing the wrong points after flipping the row, and,
						// don't want to clutter with noise from every single row scan -- just the scans
						// that start on the center line.
						if (hints != null && hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
						{
							System.Collections.Hashtable newHints = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable()); // Can't use clone() in J2ME
							System.Collections.IEnumerator hintEnum = hints.Keys.GetEnumerator();
							//UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
							while (hintEnum.MoveNext())
							{
								//UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
								System.Object key = hintEnum.Current;
								if (!key.Equals(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
								{
									newHints[key] = hints[key];
								}
							}
							hints = newHints;
						}
					}
					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, (System.Object) 180);
							// And remember to flip the result points horizontally.
							ResultPoint[] points = result.ResultPoints;
							points[0] = new ResultPoint(width - points[0].X - 1, points[0].Y);
							points[1] = new ResultPoint(width - points[1].X - 1, points[1].Y);
						}
						return result;
					}
					catch (ReaderException)
					{
						// continue -- just couldn't decode this row
					}
				}
			}
			
			throw ReaderException.Instance;
		}
Exemplo n.º 52
0
        /// <summary> Locate the vertices and the codewords area of a black blob using the Start
        /// and Stop patterns as locators. This assumes that the image is rotated 180
        /// degrees and if it locates the start and stop patterns at it will re-map
        /// the vertices for a 0 degree rotation.
        /// TODO: Change assumption about barcode location.
        /// TODO: Scanning every row is very expensive. We should only do this for TRY_HARDER.
        ///
        /// </summary>
        /// <param name="matrix">the scanned barcode image.
        /// </param>
        /// <returns> an array containing the vertices:
        /// vertices[0] x, y top left barcode
        /// vertices[1] x, y bottom left barcode
        /// vertices[2] x, y top right barcode
        /// vertices[3] x, y bottom right barcode
        /// vertices[4] x, y top left codeword area
        /// vertices[5] x, y bottom left codeword area
        /// vertices[6] x, y top right codeword area
        /// vertices[7] x, y bottom right codeword area
        /// </returns>
        private static ResultPoint[] findVertices180(BitMatrix matrix)
        {
            int height    = matrix.Height;
            int width     = matrix.Width;
            int halfWidth = width >> 1;

            ResultPoint[] result = new ResultPoint[8];
            bool          found  = false;

            // Top Left
            for (int i = height - 1; i > 0; i--)
            {
                int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
                if (loc != null)
                {
                    result[0] = new ResultPoint(loc[1], i);
                    result[4] = new ResultPoint(loc[0], i);
                    found     = true;
                    break;
                }
            }
            // Bottom Left
            if (found)
            {
                // Found the Top Left vertex
                found = false;
                for (int i = 0; i < height; i++)
                {
                    int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
                    if (loc != null)
                    {
                        result[1] = new ResultPoint(loc[1], i);
                        result[5] = new ResultPoint(loc[0], i);
                        found     = true;
                        break;
                    }
                }
            }
            // Top Right
            if (found)
            {
                // Found the Bottom Left vertex
                found = false;
                for (int i = height - 1; i > 0; i--)
                {
                    int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
                    if (loc != null)
                    {
                        result[2] = new ResultPoint(loc[0], i);
                        result[6] = new ResultPoint(loc[1], i);
                        found     = true;
                        break;
                    }
                }
            }
            // Bottom Right
            if (found)
            {
                // Found the Top Right vertex
                found = false;
                for (int i = 0; i < height; i++)
                {
                    int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
                    if (loc != null)
                    {
                        result[3] = new ResultPoint(loc[0], i);
                        result[7] = new ResultPoint(loc[1], i);
                        found     = true;
                        break;
                    }
                }
            }
            return(found?result:null);
        }
Exemplo n.º 53
0
        internal virtual FinderPatternInfo find(System.Collections.Hashtable hints)
        {
            bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
            int  maxI      = image.Height;
            int  maxJ      = image.Width;
            // We are looking for black/white/black/white/black modules in
            // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far

            // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
            // image, and then account for the center being 3 modules in size. This gives the smallest
            // number of pixels the center could be, so skip this often. When trying harder, look for all
            // QR versions regardless of how dense they are.
            int iSkip = (3 * maxI) / (4 * MAX_MODULES);

            if (iSkip < MIN_SKIP || tryHarder)
            {
                iSkip = MIN_SKIP;
            }

            bool done = false;

            int[] stateCount = new int[5];
            for (int i = iSkip - 1; i < maxI && !done; i += iSkip)
            {
                // Get a row of black/white values
                stateCount[0] = 0; // black
                stateCount[1] = 0; // white
                stateCount[2] = 0; // black
                stateCount[3] = 0; // white
                stateCount[4] = 0; // black
                int currentState = 0;
                for (int j = 0; j < maxJ; j++)
                {
                    if (image.get_Renamed(j, i))
                    {
                        // Black pixel
                        if ((currentState % 2) == 1)                         // if currentState is White (i.e. 1 or 3)
                        {
                            // Counting white pixels
                            currentState++;
                        }
                        stateCount[currentState]++;
                    }
                    else
                    {
                        // White pixel
                        if ((currentState % 2) == 0)
                        {
                            // Counting black pixels
                            if (currentState == 4)
                            {
                                // A winner?
                                if (foundPatternCross(stateCount))
                                {
                                    // Yes
                                    bool confirmed = handlePossibleCenter(stateCount, i, j);
                                    if (confirmed)
                                    {
                                        // Start examining every other line. Checking each line turned out to be too
                                        // expensive and didn't improve performance.
                                        iSkip = 2;
                                        if (hasSkipped)
                                        {
                                            done = haveMultiplyConfirmedCenters();
                                        }
                                        else
                                        {
                                            int rowSkip = findRowSkip();
                                            if (rowSkip > stateCount[2])
                                            {
                                                // Skip rows between row of lower confirmed center
                                                // and top of presumed third confirmed center
                                                // but back up a bit to get a full chance of detecting
                                                // it, entire width of center of finder pattern

                                                // Skip by rowSkip, but back off by stateCount[2] (size of last center
                                                // of pattern we saw) to be conservative, and also back off by iSkip which
                                                // is about to be re-added
                                                i += rowSkip - stateCount[2] - iSkip;
                                                j  = maxJ - 1;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // Advance to next black pixel
                                        do
                                        {
                                            j++;
                                        }while (j < maxJ && !image.get_Renamed(j, i));
                                        j--;                                         // back up to that last white pixel
                                    }
                                    // Clear state to start looking again
                                    currentState  = 0;
                                    stateCount[0] = 0;
                                    stateCount[1] = 0;
                                    stateCount[2] = 0;
                                    stateCount[3] = 0;
                                    stateCount[4] = 0;
                                }
                                else
                                {
                                    // No, shift counts back by two
                                    stateCount[0] = stateCount[2];
                                    stateCount[1] = stateCount[3];
                                    stateCount[2] = stateCount[4];
                                    stateCount[3] = 1;
                                    stateCount[4] = 0;
                                    currentState  = 3;
                                }
                            }
                            else
                            {
                                stateCount[++currentState]++;
                            }
                        }
                        else
                        {
                            // Counting white pixels
                            stateCount[currentState]++;
                        }
                    }
                }
                if (foundPatternCross(stateCount))
                {
                    bool confirmed = handlePossibleCenter(stateCount, i, maxJ);
                    if (confirmed)
                    {
                        iSkip = stateCount[0];
                        if (hasSkipped)
                        {
                            // Found a third one
                            done = haveMultiplyConfirmedCenters();
                        }
                    }
                }
            }

            FinderPattern[] patternInfo = selectBestPatterns();
            if (patternInfo.IsBlank())
            {
                return(null);
            }

            ResultPoint.orderBestPatterns(patternInfo);

            return(new FinderPatternInfo(patternInfo));
        }
Exemplo n.º 54
0
        /// <summary>
        /// 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".
        /// </summary>
        /// <param name="image"> The image to decode </param>
        /// <param name="hints"> Any hints that were requested </param>
        /// <returns> The contents of the decoded barcode </returns>
        /// <exception cref="NotFoundException"> Any spontaneous errors which occur </exception>
        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        //ORIGINAL LINE: private com.google.zxing.Result doDecode(com.google.zxing.BinaryBitmap image, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.NotFoundException
        private Result doDecode(BinaryBitmap image, IDictionary<DecodeHintType, object> hints)
        {
            int width = image.Width;
            int height = image.Height;
            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 ? 8 : 5));
            int maxLines;
            if (tryHarder)
            {
              maxLines = height; // Look at the whole image, not just the center
            }
            else
            {
              maxLines = 15; // 15 rows spaced 1/32 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
              {
            row = image.getBlackRow(rowNumber, row);
              }
              catch (NotFoundException nfe)
              {
            continue;
              }

              // 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
              // This means we will only ever draw result points *once* in the life of this method
              // since we want to avoid drawing the wrong points after flipping the row, and,
              // don't want to clutter with noise from every single row scan -- just the scans
              // that start on the center line.
              if (hints != null && hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
              {
                //IDictionary<DecodeHintType, object> newHints = new EnumMap<DecodeHintType, object>(typeof(DecodeHintType));
                  Dictionary<DecodeHintType,object> newHints = new Dictionary<DecodeHintType,object>();
            //JAVA TO C# CONVERTER TODO TASK: There is no .NET Dictionary equivalent to the Java 'putAll' method:
                //newHints.putAll(hints);
                //foreach (DecodeHintType dht in Enum.GetValues(typeof(DecodeHintType)))
                //{
                //    newHints.Add(dht,dht);
                //}
                foreach (KeyValuePair<DecodeHintType,object> kvp in hints)
                {
                    newHints.Add(kvp.Key,kvp.Value);
                }

                if (newHints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
                {
                    newHints.Remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
                }
                hints = newHints;
              }
            }
            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.ResultPoints;
                if (points != null)
                {
                  points[0] = new ResultPoint(width - points[0].X - 1, points[0].Y);
                  points[1] = new ResultPoint(width - points[1].X - 1, points[1].Y);
                }
              }
              return result;
            }
            catch (ReaderException re)
            {
              // continue -- just couldn't decode this row
            }
              }
            }

            throw NotFoundException.NotFoundInstance;
        }