public static byte[] Read(byte[] bytes, int width, int height, uint tolerance, byte[] debugBytes = null) { TagImage tagImage = new TagImage() { Bytes = bytes, Width = width, Height = height, ColorDifferenceTolerance = tolerance }; #if DEBUG if (debugBytes != null) { _debugImage = new TagImage() { Bytes = debugBytes, Width = width, Height = height }; } #endif tagImage.BaseColor = tagImage.ReadColor(tagImage.CenterX, tagImage.CenterY); int maxIterations = Mathf.Min(width, height) / 32; if (maxIterations <= 0) { return(null); } if (!TryFindTagCenterCoordinatesAndRadius(tagImage, maxIterations)) { return(null); } if (!TryFindStartingAngleAndSegmentSize(tagImage)) { return(null); } if (!TryFindLayerSizeAndCount(tagImage)) { return(null); } return(TryReadData(tagImage, out byte[] readBytes) ? readBytes : null); }
private static bool TryFindLayerSizeAndCount(TagImage tagImage) { int layerSize = 0; int layerCount = 0; double angle = tagImage.CodeStartingAngle + tagImage.CodeSegmentSize / 2.0; int startingIndex = tagImage.CodeRadius; uint dataColor = 0; int usedWidth = Math.Min(tagImage.CodeCenterX, tagImage.Width / 2); // Find layer size for (int i = startingIndex; i < tagImage.Width; i++) { CalculateCoords(tagImage, angle, i, out int x, out int y); if (x < 0 || y < 0 || x > tagImage.Width || y > tagImage.Height) { continue; } uint color = tagImage.ReadColor(x, y); uint diff = tagImage.ColorDiff(color); if (diff < tagImage.ColorDifferenceTolerance) { continue; } dataColor = color; layerSize = i - startingIndex - 1; startingIndex = i; break; } if (layerSize == 0 || layerSize == usedWidth) { return(false); } // Find size of the tag data block (layer size * layer count, starting from the first data layer) int dataSize = -1; for (int i = startingIndex; i < tagImage.Width; i++) { CalculateCoords(tagImage, angle, i, out int x, out int y); if (x < 0 || y < 0 || x > tagImage.Width || y > tagImage.Height) { continue; } uint color = tagImage.ReadColor(x, y); uint diff = TagImage.ColorDiff(color, dataColor); if (diff < tagImage.ColorDifferenceTolerance) { continue; } dataSize = i - startingIndex - 1; break; } if (dataSize < 0) { return(false); } layerCount = (int)Math.Round((double)dataSize / (double)layerSize); tagImage.CodeLayerSize = layerSize; tagImage.CodeLayerCount = layerCount; return(true); }