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

📄 qrcodeimagereader.java

📁 一款用Java实现QR解码的源代码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package jp.sourceforge.qrcode.codec.reader;


import jp.sourceforge.qrcode.codec.data.*;
import jp.sourceforge.qrcode.codec.exception.AlignmentPatternEdgeNotFoundException;
import jp.sourceforge.qrcode.codec.exception.FinderPatternNotFoundException;
import jp.sourceforge.qrcode.codec.exception.VersionInformationException;
import jp.sourceforge.qrcode.codec.geom.*;
import jp.sourceforge.qrcode.codec.reader.pattern.*;
import jp.sourceforge.qrcode.codec.util.*;

public class QRCodeImageReader {

	DebugCanvas canvas;
	//boolean[][] image;
	//DP = 
	//23 ... max 255
	//22 .. max 511
	//21 .. max 1023
	public static int DECIMAL_POINT = 22;
	public static final boolean POINT_DARK = true;
	public static final boolean POINT_LIGHT = false;

	//int numModuleAtSide; //僨僐乕僪懳徾偺僔儞儃儖偵偍偗傞堦曈偺儌僕儏乕儖偺悢

	public QRCodeImageReader() {
		//this.image = image;
		this.canvas = DebugCanvas.getCanvas();
	}
	
	
	boolean[][] applyMedianFilter(boolean[][] image, int threshold, int internalScale) {//threshold,阈值
		boolean[][] filteredMatrix = new boolean[image.length][image[0].length];
		//僲僀僘僼傿儖僞(儊僨傿傾儞僼傿儖僞)
		int numPointDark;
		for (int y = internalScale; y < image[0].length - internalScale; y+=internalScale) {
			for (int x = internalScale; x < image.length - internalScale; x+=internalScale) {
				//if (image[x][y] == true) {
					numPointDark = 0;
					for (int fy = -internalScale; fy < internalScale + 1; fy+=internalScale) {
						for (int fx = -internalScale; fx < internalScale + 1; fx+=internalScale) {
							if (image[x + fx][y + fy] == true) {
								numPointDark++;
							}
						}
					}
					if (numPointDark > threshold) {
						for (int dy = 0; dy < internalScale; dy++)
							for (int dx = 0; dx < internalScale; dx++)
						filteredMatrix[x + dx][y + dy] = POINT_DARK;
					}
				//}
			}
		}
		return filteredMatrix;
	}
	
	public QRCodeSymbol getQRCodeSymbol(boolean[][] image, int internalScale) 
			throws FinderPatternNotFoundException ,
			VersionInformationException ,
			AlignmentPatternEdgeNotFoundException {
		int longSide = (image.length < image[0].length) ? image[0].length : image.length;
//		if (longSide < 255)
			QRCodeImageReader.DECIMAL_POINT = 23 - QRCodeUtility.sqrt(longSide / 256);
			
		canvas.println("Drawing matrix.");
		canvas.drawMatrix(image);
		//for(int i = 0; i < 500000; i++) System.out.println("");

		canvas.println("Scanning Finder Pattern.");
		FinderPattern finderPattern = null;
		try {
			finderPattern = FinderPattern.findFinderPattern(image);
		} catch (FinderPatternNotFoundException e) {
			canvas.println("Not found, now retrying...");
			image = applyMedianFilter(image, 5, internalScale);
			canvas.drawMatrix(image);
			try {
				finderPattern = FinderPattern.findFinderPattern(image);
			} catch (FinderPatternNotFoundException e2) {
				e2.printStackTrace();
				throw e2;
			} catch (VersionInformationException e3) {
				throw e3;
			}
			
//			if (finderPattern.getCenter() == null) {
//				canvas.println("ERROR: Finder pattern not found");				
//			}
		} catch (VersionInformationException e4) {
			throw e4;
		}


		canvas.println("FinderPattern at");
		String finderPatternCoordinates = 
			finderPattern.getCenter(FinderPattern.UL).toString() + 
			finderPattern.getCenter(FinderPattern.UR).toString() +
			finderPattern.getCenter(FinderPattern.DL).toString();
		canvas.println(finderPatternCoordinates);
 		int[] sincos = finderPattern.getAngle();
		canvas.println("Angle*4098: Sin " + Integer.toString(sincos[0]) + "  " + "Cos " + Integer.toString(sincos[1]));

		Line[][][][] samplingGrid = new Line[1][1][1][1];
		int version = finderPattern.getVersion();

		canvas.println("Version: " + Integer.toString(version));

		AlignmentPattern alignmentPattern = null;
		if (version > 1) {
			try {
				alignmentPattern = AlignmentPattern.findAlignmentPattern(image, finderPattern);
			} catch (AlignmentPatternEdgeNotFoundException e) {
				e.printStackTrace();
				throw e;
			}
			
			int matrixLength = alignmentPattern.getCenter().length;
			canvas.println("AlignmentPatterns at");
			for (int y = 0; y < matrixLength; y++) {
				String alignmentPatternCoordinates = "";
				for (int x = 0; x < matrixLength; x++) {
					alignmentPatternCoordinates += alignmentPattern.getCenter()[x][y].toString();
				}
				canvas.println(alignmentPatternCoordinates);
			}
		}
		//for(int i = 0; i < 500000; i++) System.out.println("");

		canvas.println("Creating sampling grid.");
		//[TODO] need all-purpose method
		if (version == 1)
			samplingGrid = getSamplingGrid1(finderPattern);
		else if (version >= 2 && version <= 6)
			samplingGrid = getSamplingGrid2_6(finderPattern, alignmentPattern);
		else if (version >= 7 && version <= 13)
			samplingGrid = getSamplingGrid7_13(finderPattern, alignmentPattern);
//		else if (version >= 14 && version <= 20)
//			samplingGrid = getSamplingGrid14_20(finderPattern, alignmentPattern);			
		canvas.println("Reading grid.");
		boolean[][] qRCodeMatrix = getQRCodeMatrix(image, samplingGrid);
		//canvas.drawMatrix(qRCodeMatrix, 5);
		
		return new QRCodeSymbol(qRCodeMatrix);
	}
	
	//埵抲崌偣僷僞乕儞偑側偄宆斣1愱梡
	Line[][][][] getSamplingGrid1(FinderPattern finderPattern) {
		int sqrtNumArea = 1;
		int sqrtNumModules = finderPattern.getSqrtNumModules(); //堦曈摉偨傝偺儌僕儏乕儖悢傪摼傞
		int sqrtNumAreaModules = sqrtNumModules / sqrtNumArea;
		Point[] centers = finderPattern.getCenter();
		int logicalDistance = 14;
		Line[][][][] samplingGrid = new Line[sqrtNumArea][sqrtNumArea][2][sqrtNumAreaModules];
		Line baseLineX, baseLineY, gridLineX, gridLineY;

		//儌僕儏乕儖僺僢僠傪摼傞
		int[] modulePitch = new int[2]; //up left 偺弴偵奿擺
		modulePitch[0] = getAreaModulePitch(centers[0], centers[1], logicalDistance);
		modulePitch[1] = getAreaModulePitch(centers[0], centers[2], logicalDistance);

		//X幉偵悅捈偺婎慄(堦斒偵廲)
		baseLineX = new Line(
				finderPattern.getCenter(FinderPattern.UL), 
				finderPattern.getCenter(FinderPattern.DL));

		int sin = finderPattern.getAngle()[0];
		int cos = finderPattern.getAngle()[1];

		Axis axis = new Axis(sin, cos, modulePitch[0]);
		axis.setOrigin(baseLineX.getP1());
		baseLineX.setP1(axis.translate(-3, -3));


		axis.setModulePitch(modulePitch[1]);
		axis.setOrigin(baseLineX.getP2());
		baseLineX.setP2(axis.translate(-3, 3));
						

		
		//Y幉偵悅捈偺婎慄(堦斒偵墶)
	  baseLineY =
			new Line(finderPattern.getCenter(FinderPattern.UL),
					finderPattern.getCenter(FinderPattern.UR));
	  
		axis.setModulePitch(modulePitch[1]);
		axis.setOrigin(baseLineY.getP1());
		baseLineY.setP1(axis.translate(-3, -3));


		axis.setModulePitch(modulePitch[1]);
		axis.setOrigin(baseLineY.getP2());
		baseLineY.setP2(axis.translate(3, -3));
		
		baseLineX.translate(1,1);
		baseLineY.translate(1,1);

		for (int i = 0; i < sqrtNumAreaModules; i++) {
			
			gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());
			
			axis.setOrigin(gridLineX.getP1());
			axis.setModulePitch(modulePitch[0]);
			gridLineX.setP1(axis.translate(i,0));

			axis.setOrigin(gridLineX.getP2());
			axis.setModulePitch(modulePitch[0]);
			gridLineX.setP2(axis.translate(i,0));
			

			gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
			axis.setOrigin(gridLineY.getP1());
			axis.setModulePitch(modulePitch[1]);
			gridLineY.setP1(axis.translate(0,i));

			axis.setOrigin(gridLineY.getP2());
			axis.setModulePitch(modulePitch[1]);
			gridLineY.setP2(axis.translate(0,i));


			samplingGrid[0][0][0][i] = gridLineX;
			samplingGrid[0][0][1][i] = gridLineY;
		}
		for (int ay = 0; ay < samplingGrid[0].length; ay++) {
			for (int ax = 0; ax < samplingGrid.length; ax++) {
				canvas.drawLines(samplingGrid[ax][ay][0], Color.LIGHTBLUE);
				canvas.drawLines(samplingGrid[ax][ay][1], Color.LIGHTBLUE);
			}
		}
		return samplingGrid;
	}
	
	//sampllingGrid[areaX][areaY][direction(x=0,y=1)][EachLines]	
	//宆斣2 乣 6偺僒儞僾儕儞僌僌儕僢僪傪媮傔傞
	Line[][][][] getSamplingGrid2_6(FinderPattern finderPattern, AlignmentPattern alignmentPattern) {

		Point centers[][] = alignmentPattern.getCenter();
		centers[0][0] = finderPattern.getCenter(FinderPattern.UL);
		centers[1][0] = finderPattern.getCenter(FinderPattern.UR);
		centers[0][1] = finderPattern.getCenter(FinderPattern.DL);
		int sqrtNumModules = finderPattern.getSqrtNumModules(); //堦曈摉偨傝偺儌僕儏乕儖悢傪摼傞

		Line[][][][] samplingGrid = new Line[1][1][2][sqrtNumModules];
		Line baseLineX, baseLineY, gridLineX, gridLineY;
		
		int logicalDistance = alignmentPattern.getLogicalDistance();
		int sin = finderPattern.getAngle()[0];
		int cos = finderPattern.getAngle()[1];
		Axis axis = new Axis(sin, cos, finderPattern.getModuleSize());
	
		int[] modulePitch = new int[4]; //top left bottom right偺弴偵奿擺

		modulePitch[0] = getAreaModulePitch(centers[0][0], centers[1][0], logicalDistance + 6);
		modulePitch[1] = getAreaModulePitch(centers[0][0], centers[0][1], logicalDistance + 6);
		axis.setModulePitch(modulePitch[0]);
		axis.setOrigin(centers[0][1]);
		modulePitch[2] = getAreaModulePitch(axis.translate(0, -3), centers[1][1], logicalDistance + 3);
		axis.setModulePitch(modulePitch[1]);
		axis.setOrigin(centers[1][0]);
		modulePitch[3] = getAreaModulePitch(axis.translate(-3, 0), centers[1][1], logicalDistance + 3);

		//X幉偵悅捈偺婎慄(堦斒偵廲)
		baseLineX = new Line();
		baseLineY = new Line();
		
		axis.setOrigin(centers[0][0]);
		modulePitch[0] = getAreaModulePitch(centers[0][0], centers[1][0], logicalDistance + 6);
		modulePitch[1] = getAreaModulePitch(centers[0][0], centers[0][1], logicalDistance + 6);
		axis.setModulePitch(modulePitch[0]);
		axis.setOrigin(centers[0][1]);
		modulePitch[2] = getAreaModulePitch(axis.translate(0,-3), centers[1][1], logicalDistance + 3);
		axis.setModulePitch(modulePitch[1]);
		axis.setOrigin(centers[1][0]);
		modulePitch[3] = getAreaModulePitch(axis.translate(-3,0), centers[1][1], logicalDistance + 3);
		
		
		axis.setOrigin(centers[0][0]);
		axis.setModulePitch(modulePitch[0]);
		baseLineX.setP1(axis.translate(-3,-3));

		axis.setModulePitch(modulePitch[1]);
		baseLineY.setP1(axis.translate(-3,-3));
		
		axis.setOrigin(centers[0][1]);
		axis.setModulePitch(modulePitch[2]);
		baseLineX.setP2(axis.translate(-3,3));
		
		axis.setOrigin(centers[1][0]);
		axis.setModulePitch(modulePitch[3]);
		baseLineY.setP2(axis.translate(3,-3));
		

		baseLineX.translate(1,1);
		baseLineY.translate(1,1);
		
		for (int i = 0; i < sqrtNumModules; i++) {
			gridLineX = new Line(baseLineX.getP1(), baseLineX.getP2());

			axis.setOrigin(gridLineX.getP1());
			axis.setModulePitch(modulePitch[0]);
			gridLineX.setP1(axis.translate(i,0));

			axis.setOrigin(gridLineX.getP2());
			axis.setModulePitch(modulePitch[2]);
			gridLineX.setP2(axis.translate(i,0));

			
			gridLineY = new Line(baseLineY.getP1(), baseLineY.getP2());
			
			axis.setOrigin(gridLineY.getP1());
			axis.setModulePitch(modulePitch[1]);
			gridLineY.setP1(axis.translate(0,i));

			axis.setOrigin(gridLineY.getP2());
			axis.setModulePitch(modulePitch[3]);
			gridLineY.setP2(axis.translate(0,i));
			

			samplingGrid[0][0][0][i] = gridLineX;
			samplingGrid[0][0][1][i] = gridLineY;
			
		}
		for (int ay = 0; ay < samplingGrid[0].length; ay++) {
			for (int ax = 0; ax < samplingGrid.length; ax++) {
				canvas.drawLines(samplingGrid[ax][ay][0], Color.LIGHTBLUE);
				canvas.drawLines(samplingGrid[ax][ay][1], Color.LIGHTBLUE);
			}
		}
		return samplingGrid;
	}
	

	
	//宆斣7乣13梡
	Line[][][][] getSamplingGrid7_13(FinderPattern finderPattern, AlignmentPattern alignmentPattern) {

		Point centers[][] = alignmentPattern.getCenter();
		centers[0][0] = finderPattern.getCenter(FinderPattern.UL);
		centers[2][0] = finderPattern.getCenter(FinderPattern.UR);
		centers[0][2] = finderPattern.getCenter(FinderPattern.DL);
		int sqrtNumModules = finderPattern.getSqrtNumModules(); //堦曈摉偨傝偺儌僕儏乕儖悢傪摼傞
		int sqrtNumArea = 2;
		int sqrtNumAreaModules = sqrtNumModules / sqrtNumArea;
		sqrtNumAreaModules++;
		Line[][][][] samplingGrid = new Line[sqrtNumArea][sqrtNumArea][2][sqrtNumAreaModules];
		Line baseLineX, baseLineY, gridLineX, gridLineY;
		Point[] targetCenters;
		int logicalDistance = alignmentPattern.getLogicalDistance();
		int sin = finderPattern.getAngle()[0];
		int cos = finderPattern.getAngle()[1];
		Axis axis = new Axis(sin, cos, finderPattern.getModuleSize());
		int[] modulePitch;
		for (int ay = 0; ay < sqrtNumArea; ay++) {
			for (int ax = 0; ax < sqrtNumArea; ax++) {
				modulePitch = new int[4]; //top left bottom right偺弴偵奿擺
				baseLineX = new Line();
				baseLineY = new Line();
				axis.setModulePitch(finderPattern.getModuleSize());
				if (ax == 0 && ay == 0) {
					axis.setOrigin(centers[0][0]);
					modulePitch[0] = getAreaModulePitch(axis.translate(0,3), centers[1][0], logicalDistance + 3);
					modulePitch[1] = getAreaModulePitch(axis.translate(3,0), centers[0][1], logicalDistance + 3);
					axis.setModulePitch(modulePitch[0]);
					modulePitch[2] = getAreaModulePitch(centers[0][1], centers[1][1], logicalDistance);
					axis.setModulePitch(modulePitch[1]);
					modulePitch[3] = getAreaModulePitch(centers[1][0], centers[1][1], logicalDistance);
					
					axis.setModulePitch(modulePitch[0]);
					baseLineX.setP1(axis.translate(-3,-3));

					axis.setModulePitch(modulePitch[1]);
					baseLineY.setP1(axis.translate(-3,-3));
					
					axis.setOrigin(centers[0][1]);
					axis.setModulePitch(modulePitch[2]);
					baseLineX.setP2(axis.translate(-6,0));
					
					axis.setOrigin(centers[1][0]);
					axis.setModulePitch(modulePitch[3]);
					baseLineY.setP2(axis.translate(0,-6));
				}
				else if (ax == 1 && ay == 0) {
					axis.setOrigin(centers[1][0]);
					modulePitch[0] = getAreaModulePitch(axis.translate(0,-3), centers[2][0], logicalDistance + 3);
					modulePitch[1] = getAreaModulePitch(centers[1][0], centers[1][1], logicalDistance);
					axis.setModulePitch(modulePitch[0]);
					modulePitch[2] = getAreaModulePitch(centers[1][1], centers[2][1], logicalDistance);

⌨️ 快捷键说明

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