📄 finderpattern.cs
字号:
else if (originPoint.X >= remoteLine.getP1().X & originPoint.X >= remoteLine.getP2().X)
if (remoteLine.getP1().Y < remoteLine.getP2().Y)
remotePoint = remoteLine.getP2();
else
remotePoint = remoteLine.getP1();
else if (originPoint.Y >= remoteLine.getP1().Y & originPoint.Y >= remoteLine.getP2().Y)
if (remoteLine.getP1().X < remoteLine.getP2().X)
remotePoint = remoteLine.getP1();
else
remotePoint = remoteLine.getP2();
//1st or 4th quadrant
else if (remoteLine.getP1().Y < remoteLine.getP2().Y)
remotePoint = remoteLine.getP1();
else
remotePoint = remoteLine.getP2();
int r = new Line(originPoint, remotePoint).Length;
//canvas.println(Integer.toString(((remotePoint.getX() - originPoint.getX()) << QRCodeImageReader.DECIMAL_POINT)));
int[] angle = new int[2];
angle[0] = ((remotePoint.Y - originPoint.Y) << QRCodeImageReader.DECIMAL_POINT) / r; //Sin
angle[1] = ((remotePoint.X - originPoint.X) << (QRCodeImageReader.DECIMAL_POINT)) / r; //Cos
return angle;
}
internal static Point[] getCenter(Line[] crossLines)
{
System.Collections.ArrayList centers = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
for (int i = 0; i < crossLines.Length - 1; i++)
{
Line compareLine = crossLines[i];
for (int j = i + 1; j < crossLines.Length; j++)
{
Line comparedLine = crossLines[j];
if (Line.isCross(compareLine, comparedLine))
{
int x = 0;
int y = 0;
if (compareLine.Horizontal)
{
x = compareLine.Center.X;
y = comparedLine.Center.Y;
}
else
{
x = comparedLine.Center.X;
y = compareLine.Center.Y;
}
centers.Add(new Point(x, y));
}
}
}
Point[] foundPoints = new Point[centers.Count];
for (int i = 0; i < foundPoints.Length; i++)
{
foundPoints[i] = (Point) centers[i];
//Console.out.println(foundPoints[i]);
}
//Console.out.println(foundPoints.length);
if (foundPoints.Length == 3)
{
canvas.drawPolygon(foundPoints, ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
return foundPoints;
}
else
throw new FinderPatternNotFoundException("Invalid number of Finder Pattern detected");
}
//sort center of finder patterns as Left-Up: points[0], Right-Up: points[1], Left-Down: points[2].
internal static Point[] sort(Point[] centers, int[] angle)
{
Point[] sortedCenters = new Point[3];
int quadant = getURQuadant(angle);
switch (quadant)
{
case 1:
sortedCenters[1] = getPointAtSide(centers, Point.RIGHT, Point.BOTTOM);
sortedCenters[2] = getPointAtSide(centers, Point.BOTTOM, Point.LEFT);
break;
case 2:
sortedCenters[1] = getPointAtSide(centers, Point.BOTTOM, Point.LEFT);
sortedCenters[2] = getPointAtSide(centers, Point.TOP, Point.LEFT);
break;
case 3:
sortedCenters[1] = getPointAtSide(centers, Point.LEFT, Point.TOP);
sortedCenters[2] = getPointAtSide(centers, Point.RIGHT, Point.TOP);
break;
case 4:
sortedCenters[1] = getPointAtSide(centers, Point.TOP, Point.RIGHT);
sortedCenters[2] = getPointAtSide(centers, Point.BOTTOM, Point.RIGHT);
break;
}
//last of centers is Left-Up patterns one
for (int i = 0; i < centers.Length; i++)
{
if (!centers[i].equals(sortedCenters[1]) && !centers[i].equals(sortedCenters[2]))
{
sortedCenters[0] = centers[i];
}
}
return sortedCenters;
}
internal static int getURQuadant(int[] angle)
{
int sin = angle[0];
int cos = angle[1];
if (sin >= 0 && cos > 0)
return 1;
else if (sin > 0 && cos <= 0)
return 2;
else if (sin <= 0 && cos < 0)
return 3;
else if (sin < 0 && cos >= 0)
return 4;
return 0;
}
internal static Point getPointAtSide(Point[] points, int side1, int side2)
{
Point sidePoint = new Point();
int x = ((side1 == Point.RIGHT || side2 == Point.RIGHT)?0:System.Int32.MaxValue);
int y = ((side1 == Point.BOTTOM || side2 == Point.BOTTOM)?0:System.Int32.MaxValue);
sidePoint = new Point(x, y);
for (int i = 0; i < points.Length; i++)
{
switch (side1)
{
case Point.RIGHT:
if (sidePoint.X < points[i].X)
{
sidePoint = points[i];
}
else if (sidePoint.X == points[i].X)
{
if (side2 == Point.BOTTOM)
{
if (sidePoint.Y < points[i].Y)
{
sidePoint = points[i];
}
}
else
{
if (sidePoint.Y > points[i].Y)
{
sidePoint = points[i];
}
}
}
break;
case Point.BOTTOM:
if (sidePoint.Y < points[i].Y)
{
sidePoint = points[i];
}
else if (sidePoint.Y == points[i].Y)
{
if (side2 == Point.RIGHT)
{
if (sidePoint.X < points[i].X)
{
sidePoint = points[i];
}
}
else
{
if (sidePoint.X > points[i].X)
{
sidePoint = points[i];
}
}
}
break;
case Point.LEFT:
if (sidePoint.X > points[i].X)
{
sidePoint = points[i];
}
else if (sidePoint.X == points[i].X)
{
if (side2 == Point.BOTTOM)
{
if (sidePoint.Y < points[i].Y)
{
sidePoint = points[i];
}
}
else
{
if (sidePoint.Y > points[i].Y)
{
sidePoint = points[i];
}
}
}
break;
case Point.TOP:
if (sidePoint.Y > points[i].Y)
{
sidePoint = points[i];
}
else if (sidePoint.Y == points[i].Y)
{
if (side2 == Point.RIGHT)
{
if (sidePoint.X < points[i].X)
{
sidePoint = points[i];
}
}
else
{
if (sidePoint.X > points[i].X)
{
sidePoint = points[i];
}
}
}
break;
}
}
return sidePoint;
}
internal static int[] getWidth(bool[][] image, Point[] centers, int[] sincos)
{
int[] width = new int[3];
for (int i = 0; i < 3; i++)
{
bool flag = false;
int lx, rx;
int y = centers[i].Y;
for (lx = centers[i].X; lx > 0; lx--)
{
if (image[lx][y] == QRCodeImageReader.POINT_DARK && image[lx - 1][y] == QRCodeImageReader.POINT_LIGHT)
{
if (flag == false)
flag = true;
else
break;
}
}
flag = false;
for (rx = centers[i].X; rx < image.Length; rx++)
{
if (image[rx][y] == QRCodeImageReader.POINT_DARK && image[rx + 1][y] == QRCodeImageReader.POINT_LIGHT)
{
if (flag == false)
flag = true;
else
break;
}
}
width[i] = (rx - lx + 1);
}
return width;
}
internal static int calcRoughVersion(Point[] center, int[] width)
{
int dp = QRCodeImageReader.DECIMAL_POINT;
int lengthAdditionalLine = (new Line(center[UL], center[UR]).Length) << dp;
int avarageWidth = ((width[UL] + width[UR]) << dp) / 14;
int roughVersion = ((lengthAdditionalLine / avarageWidth) - 10) / 4;
if (((lengthAdditionalLine / avarageWidth) - 10) % 4 >= 2)
{
roughVersion++;
}
return roughVersion;
}
internal static int calcExactVersion(Point[] centers, int[] angle, int[] moduleSize, bool[][] image)
{
bool[] versionInformation = new bool[18];
Point[] points = new Point[18];
Point target;
Axis axis = new Axis(angle, moduleSize[UR]); //UR
axis.Origin = centers[UR];
for (int y = 0; y < 6; y++)
{
for (int x = 0; x < 3; x++)
{
target = axis.translate(x - 7, y - 3);
versionInformation[x + y * 3] = image[target.X][target.Y];
points[x + y * 3] = target;
}
}
canvas.drawPoints(points, ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
int exactVersion = 0;
try
{
exactVersion = checkVersionInfo(versionInformation);
}
catch (InvalidVersionInfoException e)
{
canvas.println("Version info error. now retry with other place one.");
axis.Origin = centers[DL];
axis.ModulePitch = moduleSize[DL]; //DL
for (int x = 0; x < 6; x++)
{
for (int y = 0; y < 3; y++)
{
target = axis.translate(x - 3, y - 7);
versionInformation[y + x * 3] = image[target.X][target.Y];
points[x + y * 3] = target;
}
}
canvas.drawPoints(points, ThoughtWorks.QRCode.Codec.Util.Color_Fields.RED);
try
{
exactVersion = checkVersionInfo(versionInformation);
}
catch (VersionInformationException e2)
{
throw e2;
}
}
return exactVersion;
}
internal static int checkVersionInfo(bool[] target)
{
// note that this method includes BCH 18-6 Error Correction
// see page 67 on JIS-X-0510(2004)
int errorCount = 0, versionBase;
for (versionBase = 0; versionBase < VersionInfoBit.Length; versionBase++)
{
errorCount = 0;
for (int j = 0; j < 18; j++)
{
if (target[j] ^ (VersionInfoBit[versionBase] >> j) % 2 == 1)
errorCount++;
}
if (errorCount <= 3)
break;
}
if (errorCount <= 3)
return 7 + versionBase;
else
throw new InvalidVersionInfoException("Too many errors in version information");
}
static FinderPattern()
{
canvas = QRCodeDecoder.Canvas;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -