AlignmentPattern.cs
资源名称:QRCodeLib.rar [点击查看]
上传用户:tjjgrl
上传日期:2019-04-04
资源大小:1010k
文件大小:9k
源码类别:
电子政务应用
开发平台:
C#
- using System;
- using QRCodeDecoder = ThoughtWorks.QRCode.Codec.QRCodeDecoder;
- using ThoughtWorks.QRCode.Codec.Reader;
- using AlignmentPatternNotFoundException = ThoughtWorks.QRCode.ExceptionHandler.AlignmentPatternNotFoundException;
- using InvalidVersionException = ThoughtWorks.QRCode.ExceptionHandler.InvalidVersionException;
- using ThoughtWorks.QRCode.Geom;
- using ThoughtWorks.QRCode.Codec.Util;
- namespace ThoughtWorks.QRCode.Codec.Reader.Pattern
- {
- public class AlignmentPattern
- {
- internal const int RIGHT = 1;
- internal const int BOTTOM = 2;
- internal const int LEFT = 3;
- internal const int TOP = 4;
- internal static DebugCanvas canvas;
- internal Point[][] center;
- internal int patternDistance;
- virtual public int LogicalDistance
- {
- get
- {
- return patternDistance;
- }
- }
- internal AlignmentPattern(Point[][] center, int patternDistance)
- {
- this.center = center;
- this.patternDistance = patternDistance;
- }
- public static AlignmentPattern findAlignmentPattern(bool[][] image, FinderPattern finderPattern)
- {
- Point[][] logicalCenters = getLogicalCenter(finderPattern);
- int logicalDistance = logicalCenters[1][0].X - logicalCenters[0][0].X;
- //With it converts in order to handle in the same way
- Point[][] centers = null;
- centers = getCenter(image, finderPattern, logicalCenters);
- return new AlignmentPattern(centers, logicalDistance);
- }
- public virtual Point[][] getCenter()
- {
- return center;
- }
- // for only trancparency access in version 1, which has no alignement pattern
- public virtual void setCenter(Point[][] center)
- {
- this.center = center;
- }
- internal static Point[][] getCenter(bool[][] image, FinderPattern finderPattern, Point[][] logicalCenters)
- {
- int moduleSize = finderPattern.getModuleSize();
- Axis axis = new Axis(finderPattern.getAngle(), moduleSize);
- int sqrtCenters = logicalCenters.Length;
- Point[][] centers = new Point[sqrtCenters][];
- for (int i = 0; i < sqrtCenters; i++)
- {
- centers[i] = new Point[sqrtCenters];
- }
- axis.Origin = finderPattern.getCenter(FinderPattern.UL);
- centers[0][0] = axis.translate(3, 3);
- canvas.drawCross(centers[0][0], ThoughtWorks.QRCode.Codec.Util.Color_Fields.BLUE);
- axis.Origin = finderPattern.getCenter(FinderPattern.UR);
- centers[sqrtCenters - 1][0] = axis.translate(- 3, 3);
- canvas.drawCross(centers[sqrtCenters - 1][0], ThoughtWorks.QRCode.Codec.Util.Color_Fields.BLUE);
- axis.Origin = finderPattern.getCenter(FinderPattern.DL);
- centers[0][sqrtCenters - 1] = axis.translate(3, - 3);
- canvas.drawCross(centers[0][sqrtCenters - 1], ThoughtWorks.QRCode.Codec.Util.Color_Fields.BLUE);
- Point tmpPoint = centers[0][0];
- for (int y = 0; y < sqrtCenters; y++)
- {
- for (int x = 0; x < sqrtCenters; x++)
- {
- if ((x == 0 && y == 0) || (x == 0 && y == sqrtCenters - 1) || (x == sqrtCenters - 1 && y == 0))
- {
- // canvas.drawCross(centers[x][y], java.awt.Color.MAGENTA);
- continue;
- }
- Point target = null;
- if (y == 0)
- {
- if (x > 0 && x < sqrtCenters - 1)
- {
- target = axis.translate(centers[x - 1][y], logicalCenters[x][y].X - logicalCenters[x - 1][y].X, 0);
- }
- centers[x][y] = new Point(target.X, target.Y);
- canvas.drawCross(centers[x][y], ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
- }
- else if (x == 0)
- {
- if (y > 0 && y < sqrtCenters - 1)
- {
- target = axis.translate(centers[x][y - 1], 0, logicalCenters[x][y].Y - logicalCenters[x][y - 1].Y);
- }
- centers[x][y] = new Point(target.X, target.Y);
- canvas.drawCross(centers[x][y], ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
- }
- else
- {
- Point t1 = axis.translate(centers[x - 1][y], logicalCenters[x][y].X - logicalCenters[x - 1][y].X, 0);
- Point t2 = axis.translate(centers[x][y - 1], 0, logicalCenters[x][y].Y - logicalCenters[x][y - 1].Y);
- centers[x][y] = new Point((t1.X + t2.X) / 2, (t1.Y + t2.Y) / 2 + 1);
- }
- if (finderPattern.Version > 1)
- {
- Point precisionCenter = getPrecisionCenter(image, centers[x][y]);
- if (centers[x][y].distanceOf(precisionCenter) < 6)
- {
- canvas.drawCross(centers[x][y], ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
- int dx = precisionCenter.X - centers[x][y].X;
- int dy = precisionCenter.Y - centers[x][y].Y;
- canvas.println("Adjust AP(" + x + "," + y + ") to d(" + dx + "," + dy + ")");
- centers[x][y] = precisionCenter;
- }
- }
- canvas.drawCross(centers[x][y], ThoughtWorks.QRCode.Codec.Util.Color_Fields.BLUE);
- canvas.drawLine(new Line(tmpPoint, centers[x][y]), ThoughtWorks.QRCode.Codec.Util.Color_Fields.LIGHTBLUE);
- tmpPoint = centers[x][y];
- }
- }
- return centers;
- }
- internal static Point getPrecisionCenter(bool[][] image, Point targetPoint)
- {
- // find nearest dark point and update it as new rough center point
- // when original rough center points light point
- int tx = targetPoint.X, ty = targetPoint.Y;
- if ((tx < 0 || ty < 0) || (tx > image.Length - 1 || ty > image[0].Length - 1))
- throw new AlignmentPatternNotFoundException("Alignment Pattern finder exceeded out of image");
- if (image[targetPoint.X][targetPoint.Y] == QRCodeImageReader.POINT_LIGHT)
- {
- int scope = 0;
- bool found = false;
- while (!found)
- {
- scope++;
- for (int dy = scope; dy > - scope; dy--)
- {
- for (int dx = scope; dx > - scope; dx--)
- {
- int x = targetPoint.X + dx;
- int y = targetPoint.Y + dy;
- if ((x < 0 || y < 0) || (x > image.Length - 1 || y > image[0].Length - 1))
- throw new AlignmentPatternNotFoundException("Alignment Pattern finder exceeded out of image");
- if (image[x][y] == QRCodeImageReader.POINT_DARK)
- {
- targetPoint = new Point(targetPoint.X + dx, targetPoint.Y + dy);
- found = true;
- }
- }
- }
- }
- }
- int x2, lx, rx, y2, uy, dy2;
- x2 = lx = rx = targetPoint.X;
- y2 = uy = dy2 = targetPoint.Y;
- // GuoQing Hu's FIX
- while (lx >= 1 && !targetPointOnTheCorner(image, lx, y2, lx - 1, y2))
- lx--;
- while (rx < image.Length - 1 && !targetPointOnTheCorner(image, rx, y2, rx + 1, y2))
- rx++;
- while (uy >= 1 && !targetPointOnTheCorner(image, x2, uy, x2, uy - 1))
- uy--;
- while (dy2 < image[0].Length - 1 && !targetPointOnTheCorner(image, x2, dy2, x2, dy2 + 1))
- dy2++;
- return new Point((lx + rx + 1) / 2, (uy + dy2 + 1) / 2);
- }
- internal static bool targetPointOnTheCorner(bool[][] image, int x, int y, int nx, int ny)
- {
- if (x < 0 || y < 0 || nx < 0 || ny < 0 || x > image.Length || y > image[0].Length || nx > image.Length || ny > image[0].Length)
- {
- // Console.out.println("Overflow: x="+x+", y="+y+" nx="+nx+" ny="+ny+" x.max="+image.length+", y.max="+image[0].length);
- throw new AlignmentPatternNotFoundException("Alignment Pattern Finder exceeded image edge");
- //return true;
- }
- else
- {
- return (image[x][y] == QRCodeImageReader.POINT_LIGHT && image[nx][ny] == QRCodeImageReader.POINT_DARK);
- }
- }
- //get logical center coordinates of each alignment patterns
- public static Point[][] getLogicalCenter(FinderPattern finderPattern)
- {
- int version = finderPattern.Version;
- Point[][] logicalCenters = new Point[1][];
- for (int i = 0; i < 1; i++)
- {
- logicalCenters[i] = new Point[1];
- }
- int[] logicalSeeds = new int[1];
- //create "column(row)-coordinates" which based on relative coordinates
- //int sqrtCenters = (version / 7) + 2;
- //logicalSeeds = new int[sqrtCenters];
- //for(int i=0 ; i<sqrtCenters ; i++) {
- // logicalSeeds[i] = 6 + i * (4 + 4 * version) / (sqrtCenters - 1);
- // logicalSeeds[i] -= (logicalSeeds[i] - 2) % 4;
- //}
- logicalSeeds = LogicalSeed.getSeed(version);
- logicalCenters = new Point[logicalSeeds.Length][];
- for (int i2 = 0; i2 < logicalSeeds.Length; i2++)
- {
- logicalCenters[i2] = new Point[logicalSeeds.Length];
- }
- //create real relative coordinates
- for (int col = 0; col < logicalCenters.Length; col++)
- {
- for (int row = 0; row < logicalCenters.Length; row++)
- {
- logicalCenters[row][col] = new Point(logicalSeeds[row], logicalSeeds[col]);
- }
- }
- return logicalCenters;
- }
- static AlignmentPattern()
- {
- canvas = QRCodeDecoder.Canvas;
- }
- }
- }