⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finderpattern.java

📁 一款用Java实现QR解码的源代码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		sincos[0] = ((remotePoint.getY() - originPoint.getY()) << QRCodeImageReader.DECIMAL_POINT) / r; //Sin
		sincos[1] = ((remotePoint.getX() - originPoint.getX()) << QRCodeImageReader.DECIMAL_POINT) / r; //Cos
//		sincos[0] = (sincos[0] == 0) ? 1 : sincos[0];
//		sincos[1] = (sincos[1] == 0) ? 1 : sincos[1];
		return sincos;
	}
	

	
	
	static Point[] getCenter(Line[] crossLines) 
			throws FinderPatternNotFoundException {
		Vector centers = new Vector();
		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.isHorizontal()) {
						x = compareLine.getCenter().getX();
						y = comparedLine.getCenter().getY();		
					}
					else {
						x = comparedLine.getCenter().getX();
						y = compareLine.getCenter().getY();
					}
					centers.addElement(new Point(x,y));
				}
			}
		}
		
		Point[] foundPoints = new Point[centers.size()];
		
		for (int i = 0; i < foundPoints.length; i++) {
			foundPoints[i] = (Point)centers.elementAt(i);
		}

		if (foundPoints.length == 3) {
			canvas.drawPolygon(foundPoints, Color.LIGHTRED);	
			return foundPoints;
		}
		else
			throw new FinderPatternNotFoundException();
	}

	
	//奺埵抲梫慺専弌僷僞乕儞偺拞怱揰傪奿擺偟偨攝楍傪丄
	//嵍忋 points[0] 塃忋 points[1] 嵍壓 points[2]偵側傞傛偆偵僜乕僩偡傞
	static Point[] sort(Point[] centers, int[] sincos) {
		int sin = sincos[0];
		int cos = sincos[1];
		
		Point[] sortedCenters = new Point[3];
		
		int quadant = getURQuadant(sincos);
		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;
		}

		//嵟屻偵嵍忋偺僷僞乕儞傪挷傋傞
		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;
	}
	
	static int getURQuadant(int[] sincos) {
		int sin = sincos[0];
		int cos = sincos[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;
	}
	
	static Point getPointAtSide(Point[] points, int side1, int side2) {
		Point sidePoint = new Point();
		int x = ((side1 == Point.RIGHT || side2 == Point.RIGHT) ? 0 : Integer.MAX_VALUE);
		int y = ((side1 == Point.BOTTOM || side2 == Point.BOTTOM) ? 0 : Integer.MAX_VALUE);
		sidePoint = new Point(x, y);
			
		for (int i = 0; i < points.length; i++) {
			switch (side1) {
			case Point.RIGHT:
				if (sidePoint.getX() < points[i].getX()) {
					sidePoint = points[i];
				}
				else if (sidePoint.getX() == points[i].getX()) {
					if (side2 == Point.BOTTOM) {
						if (sidePoint.getY() < points[i].getY()) {
							sidePoint = points[i];
						}
					}
					else {
						if (sidePoint.getY() > points[i].getY()) {
							sidePoint = points[i];
						}
					}
				}
				break;
			case Point.BOTTOM:
				if (sidePoint.getY() < points[i].getY()) {
					sidePoint = points[i];
				}
				else if (sidePoint.getY() == points[i].getY()) {
					if (side2 == Point.RIGHT) {
						if (sidePoint.getX() < points[i].getX()) {
							sidePoint = points[i];
						}
					}
					else {
						if (sidePoint.getX() > points[i].getX()) {
							sidePoint = points[i];
						}
					}
				}
				break;
			case Point.LEFT:
				if (sidePoint.getX() > points[i].getX()) {
					sidePoint = points[i];
				}
				else if (sidePoint.getX() == points[i].getX()) {
					if (side2 == Point.BOTTOM) {
						if (sidePoint.getY() < points[i].getY()) {
							sidePoint = points[i];
						}
					}
					else {
						if (sidePoint.getY() > points[i].getY()) {
							sidePoint = points[i];
						}
					}
				}
				break;
			case Point.TOP:
				if (sidePoint.getY() > points[i].getY()) {
					sidePoint = points[i];
				}
				else if (sidePoint.getY() == points[i].getY()) {
					if (side2 == Point.RIGHT) {
						if (sidePoint.getX() < points[i].getX()) {
							sidePoint = points[i];
						}
					}
					else {
						if (sidePoint.getX() > points[i].getX()) {
							sidePoint = points[i];
						}
					}
				}
				break;
			}
		}
		return sidePoint;
	}
	
	//埵抲梫慺専弌僷僞乕儞偺暆傪媮傔傞
	static int[] getWidth(Line[] crossLines, Point[] centers,  int[] sincos) {
		int sin = sincos[0];
		int cos = sincos[1];
		int[] width = new int[3];
		for (int i = 0; i < crossLines.length; i++) {
			for (int j = i; j < crossLines.length; j++) {
				if (Line.isCross(crossLines[i], crossLines[j])) {
					if (crossLines[i].isHorizontal()) {
						for (int k = 0; k < centers.length; k++) {
							if (crossLines[i].getCenter().getX() ==
									centers[k].getX() && 
									crossLines[j].getCenter().getY() ==
									centers[k].getY()) {
								int y = 0;
								if (Math.abs(sin) < (1 << QRCodeImageReader.DECIMAL_POINT) / 2) //Threshold 45 degree
									y = (crossLines[i].getLength() * sin) >> QRCodeImageReader.DECIMAL_POINT;
								else
									y = (crossLines[i].getLength() * cos) >> QRCodeImageReader.DECIMAL_POINT;

								int r = crossLines[i].getLength();
								width[k] = QRCodeUtility.sqrt(r * r - y * y);
							}
						}
					}
					else {
						for (int k = 0; k < centers.length; k++) {
							if (crossLines[j].getCenter().getX() ==
								centers[k].getX() && 
								crossLines[i].getCenter().getY() ==
								centers[k].getY()) {
								int y = 0;
								//戞1徾尷傑偨偼戞3徾尷
								if (Math.abs(sin) < 2897) //Threshold 45 degree
									y = crossLines[i].getLength() * sin >> 12;
								else
									y = crossLines[i].getLength() * cos >> 12;
							
								int r = crossLines[j].getLength();
								width[k] = QRCodeUtility.sqrt(r * r - y * y);
							}	
						}
					}
				}
			}
		}
		return width;
	}

	//宆斣傪壖偵媮傔傞
	static int calcRoughVersion(Point[] center, int[] width) {
		final int dp = QRCodeImageReader.DECIMAL_POINT;
		int lengthAdditionalLine = (new Line(center[UL], center[UR]).getLength()) << dp ;
		//System.out.println("lengthAdditionalLine" + Integer.toString(lengthAdditionalLine));
		int avarageWidth = ((width[UL] + width[UR]) << dp) / 14;
		//System.out.println("avarageWidth:" + Integer.toBinaryString(avarageWidth));
		int roughVersion = ((lengthAdditionalLine / avarageWidth) - 10) / 4;
		if (((lengthAdditionalLine / avarageWidth) - 10) % 4 >= 2) {
			roughVersion++;
		}
		//if (tempVersion % 4096 < 2048)
			//tempVersion >>= QRCodeImageReader.DECIMAL_POINT;

			
		//else {
		//	tempVersion >>= QRCodeImageReader.DECIMAL_POINT;
		//	tempVersion++; //寘棊偪懳嶔
		//}
		//if (tempVersion <= 6)
		return roughVersion;

		
	}
	
	static int calcExactVersion(Point[] centers, int[] sincos, int[] moduleSize, boolean[][] image) 
	throws InvalidVersionInformationException,
					UnsupportedVersionException {
			boolean[] versionInformation = new boolean[18];
			//int offsetX = -(moduleSize * 8) >> 12;
			//int offsetY = -(moduleSize * 3) >> 12;
			Point[] points = new Point[18];
			int targetX, targetY;
			int sin = sincos[0];
			int cos = sincos[1];
			Axis axis = new Axis(sin, cos, moduleSize[0]); //UR
			axis.setOrigin(centers[UR]);

			for (int y = 0; y < 6; y++) {
				for (int x = 0; x < 3; x++) {

					//targetX = finderX + ((moduleSize * (x-7)) >> QRCodeImageReader.DECIMAL_POINT);
					targetX = axis.translate(x - 7, 0).getX() + 1;
					//targetY = finderY + ((moduleSize * (y-3)) >> QRCodeImageReader.DECIMAL_POINT);
					targetY = axis.translate(0, y - 3).getY() + 1;
					versionInformation[x + y * 3] = image[targetX][targetY];
					points[x + y * 3] = new Point(targetX, targetY);
					//System.out.print(points[x + y * 3]);
					//points[x + y * 3] = axis.translate(x - 7, y - 3);
				}
				//System.out.println("");
			}
			
			canvas.drawPoints(points, Color.LIGHTRED);
			
			int exactVersion = 0;
			try {
				exactVersion = checkVersionInfo(versionInformation);
			} catch (VersionInformationException e) {
				canvas.println("Version info error. now retry with other place one.");
				axis.setOrigin(centers[DL]);
				axis.setModulePitch(moduleSize[1]); //DL
				
				for (int x = 0; x < 6; x++) {
					for (int y = 0; y < 3; y++) {
						//targetX = finderX + ((moduleSize * (x-7)) >> QRCodeImageReader.DECIMAL_POINT);
						targetX = axis.translate(x - 3, 0).getX();
						//targetY = finderY + ((moduleSize * (y-3)) >> QRCodeImageReader.DECIMAL_POINT);
						targetY = axis.translate(0, y - 7).getY();
						versionInformation[y + x * 3] = image[targetX][targetY];
						points[x + y * 3] = new Point(targetX, targetY);
						//System.out.println(points[x + y * 3]);
						//canvas.drawCross(points[x + y * 3], Color.LIGHTRED);
						//System.out.print(points[x + y * 3]);
						//points[x + y * 3] = axis.translate(x - 7, y - 3);
					}
					//System.out.println("");
				}
				canvas.drawPoints(points, Color.LIGHTRED);
				
				try {
					exactVersion = checkVersionInfo(versionInformation);
				} catch (VersionInformationException e2) {
					e.printStackTrace();
					throw e2;
				}
			}
			//System.out.println("VersionInfo error");

			return exactVersion;
	}
	
	static int checkVersionInfo(boolean[] target)
			throws InvalidVersionInformationException{
		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 InvalidVersionInformationException();
	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -