/// <summary> /// <p>Detects a QR Code in an image.</p> /// </summary> /// <returns> /// <see cref="DetectorResult"/> encapsulating results of detecting a QR Code /// </returns> public virtual DetectorResult Detect() { FinderPatternFinder finder = new FinderPatternFinder(image); FinderPatternInfo info = finder.Find(); if (info == null) { return(null); } return(ProcessFinderPatternInfo(info)); }
/// <summary> /// Processes the finder pattern info. /// </summary> /// <param name="info">The info.</param> /// <returns></returns> 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) { return(null); } if (!ComputeDimension(topLeft, topRight, bottomLeft, moduleSize, out int dimension)) { return(null); } Version provisionalVersion = Version.GetProvisionalVersionForDimension(dimension); if (provisionalVersion == null) { return(null); } 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) { alignmentPattern = FindAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i); if (alignmentPattern == null) { continue; } break; } // If we didn't find alignment pattern... well try anyway without it } PerspectiveTransform transform = CreateTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension); BitMatrix bits = GridSampler.SampleGrid(image, dimension, dimension, transform); if (bits == null) { return(null); } ResultPoint[] points; if (alignmentPattern == null) { points = new ResultPoint[] { bottomLeft, topLeft, topRight }; } else { points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern }; } return(new DetectorResult(bits, points)); }