识别二维码角度

根据图像识别二维码角度

  1. pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.tykj</groupId>
    <artifactId>opencv</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>identification</name>
    <description>identification</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--        如果是 web 应用添加-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

  1. common
public class OpenCVCommon {
    public static String filePath = "E:\\java\\idea\\data\\spring\\boot\\QRCode\\code\\4.jpg";
}
  1. controller
@RestController
@RequestMapping("/opencv")
public class OpenCVController {

    @Autowired
    private QRCodeToolsUtils qrcodeTools;

    /**
     * 图像识别文字区域
     */
    @RequestMapping("/mat")
    public void mat(){
        Mat src = Imgcodecs.imread(OpenCVCommon.filePath ,1);
        OpenCVUtil.imgCorrection(src);
    }
    /**
     * 图像识别二维码定位
     */
    @RequestMapping("/direction")
    public void direction(){
        Point[] points =  new OpenCVQrCodePosition().getPosition(OpenCVCommon.filePath);
        if(points == null) {
            System.out.println("可能不包含二维码:"+OpenCVCommon.filePath);
            return;
        }
        for (int i = 0; i < points.length; i++) {
            Point p = points[i];
            System.out.println("点" + i + ": " + "(" + p.x + "," + p.y + ")");
        }
        String qrCodeText = OpenCVQrCodePosition.decodeQRcode(OpenCVCommon.filePath);
        System.out.println("二维码内容:"+ qrCodeText);
    }
    /**
     * 图像识别二维码位置
     */
    @RequestMapping("/position")
    public Integer position(){
        Integer encode = qrcodeTools.deEncodeByPath("E:\\java\\idea\\data\\spring\\boot\\QRCode\\code\\30.jpg");
        return encode;
    }



}

  1. utils
public class BufferedImageLuminanceSource extends LuminanceSource {

    private final BufferedImage image;
    private final int left;
    private final int top;

    public BufferedImageLuminanceSource(BufferedImage image) {
        this(image, 0, 0, image.getWidth(), image.getHeight());
    }

    public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
        super(width, height);

        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        if (left + width > sourceWidth || top + height > sourceHeight) {
            throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
        }

        for (int y = top; y < top + height; y++) {
            for (int x = left; x < left + width; x++) {
                if ((image.getRGB(x, y) & 0xFF000000) == 0) {
                    image.setRGB(x, y, 0xFFFFFFFF); // = white
                }
            }
        }

        this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
        this.image.getGraphics().drawImage(image, 0, 0, null);
        this.left = left;
        this.top = top;
    }

    public byte[] getRow(int y, byte[] row) {
        if (y < 0 || y >= getHeight()) {
            throw new IllegalArgumentException("Requested row is outside the image: " + y);
        }
        int width = getWidth();
        if (row == null || row.length < width) {
            row = new byte[width];
        }
        image.getRaster().getDataElements(left, top + y, width, 1, row);
        return row;
    }

    public byte[] getMatrix() {
        int width = getWidth();
        int height = getHeight();
        int area = width * height;
        byte[] matrix = new byte[area];
        image.getRaster().getDataElements(left, top, width, height, matrix);
        return matrix;
    }

    public boolean isCropSupported() {
        return true;
    }

    public LuminanceSource crop(int left, int top, int width, int height) {
        return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
    }

    public boolean isRotateSupported() {
        return true;
    }

    public LuminanceSource rotateCounterClockwise() {
        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
        BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g = rotatedImage.createGraphics();
        g.drawImage(image, transform, null);
        g.dispose();
        int width = getWidth();
        return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
    }

}
/**
 *  参考:https://www.cnblogs.com/huacanfly/p/9908408.html
 *  参考:https://blog.youkuaiyun.com/StrangeSir/article/details/93143177
 *  参考:https://opencv.org/releases/
 */
public class OpenCVQrCodePosition {
    private boolean isDebug = true;
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    // 获取二维码图片位置信息
    public Point[] getPosition(String imgUrl){
        Mat src = Imgcodecs.imread(imgUrl ,1);
        Mat src_gray = new Mat();

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        //彩色图转灰度图
        Imgproc.cvtColor(src ,src_gray ,Imgproc.COLOR_RGB2GRAY);
        //对图像进行平滑处理
        Imgproc.GaussianBlur(src_gray, src_gray, new Size(3,3), 0);
        //this.printImg("1-1.jpg", src_gray);

        Imgproc.Canny(src_gray,src_gray,112,255);

        //this.printImg("1-2.jpg", src_gray);
        Mat hierarchy = new Mat();

        // 寻找轮廓
        Imgproc.findContours(src_gray ,contours ,hierarchy ,Imgproc.RETR_TREE ,Imgproc.CHAIN_APPROX_NONE);
        List<MatOfPoint> markContours =  this.markContour(src_gray, contours, hierarchy);
        markContours = this.filterByAngle(markContours);
        Point[] points =  this.centerCals(markContours);
        if(points != null){
            this.cutRect(src, points, 12);
        }
        return points;
    }

    //  裁剪指定区域
    public BufferedImage cutRect(Mat src,Point[] points, int offset){
        if(points == null || points.length < 3){
            System.out.println("-------没有点---------");
            return null;
        }
        int left_x = (int)Math.min(points[0].x, Math.min(points[1].x, points[2].x)) - offset;
        int right_x = (int)Math.max(points[0].x, Math.max(points[1].x, points[2].x)) + offset;
        int y = (int)Math.min(points[0].y, Math.min(points[1].y, points[2].y)) - offset;
        Rect roiArea = new Rect(left_x, y, right_x - left_x, right_x - left_x);
        Mat dstRoi = new Mat(src, roiArea);
        this.printImg("cutRect.jpg", dstRoi);
        return this.mat2BufImg(dstRoi, ".png");
    }

    // 通过角度筛选点, 只处理正常角度二维码
    private List<MatOfPoint> filterByAngle(List<MatOfPoint> markContours) {
        // 二维码有三个角轮廓,少于三个的无法定位放弃,多余三个的循环裁剪出来
        if (markContours.size() < 3){
            return null;
        }else{
            for (int i=0; i<markContours.size()-2; i++){
                List<MatOfPoint> threePointList = new ArrayList<>();
                for (int j=i+1;j<markContours.size()-1; j++){
                    for (int k=j+1;k<markContours.size();k++){
                        threePointList.add(markContours.get(i));
                        threePointList.add(markContours.get(j));
                        threePointList.add(markContours.get(k));
                        if(capture(threePointList)){
                            return threePointList;
                        }else{
                            threePointList.clear();
                        }
                    }
                }
            }
        }
        return null;
    }

    // 计算三个点是否符合 90,45,45
    private boolean capture(List<MatOfPoint> contours){
        Point[] pointthree = this.centerCals(contours);
        double angle1 = this.angle(pointthree[1],  pointthree[0],  pointthree[2]);
        double angle2 = this.angle(pointthree[0],  pointthree[1],  pointthree[2]);
        double angle3 = this.angle(pointthree[1],  pointthree[2],  pointthree[0]);

        System.out.println("angle1:"+angle1+",angle2:"+angle2+",angle3:"+angle3);
        if (Double.isNaN(angle1) || Double.isNaN(angle2) || Double.isNaN(angle3)){
            return false;
        }

        // 最大角度和最小角度
        double maxAngle = Math.max(angle3,Math.max(angle1,angle2));
        double minAngle = Math.min(angle3,Math.min(angle1,angle2));
        if (maxAngle<85 || maxAngle>95 || minAngle < 40 || minAngle > 50){ /**二维码为直角,最大角过大或者过小都判断为不是二维码*/
            return false;
        }
        return true;
    }

    //  计算夹角
    private double angle(Point p1, Point p2, Point p3){
        double[] ca = new double[2];
        double[] cb = new double[2];

        ca[0] =  p1.x - p2.x;
        ca[1] =  p1.y - p2.y;
        cb[0] =  p3.x - p2.x;
        cb[1] =  p3.y - p2.y;
        return 180/3.1415*Math.acos((ca[0]*cb[0]+ca[1]*cb[1])/(Math.sqrt(ca[0]*ca[0]+ca[1]*ca[1])*Math.sqrt(cb[0]*cb[0]+cb[1]*cb[1])));
    }
    // 转换为点
    private Point[] centerCals(List<MatOfPoint> matOfPoint){
        if(matOfPoint == null || matOfPoint.size() == 0){
            return null;
        }
        Point[] pointthree = new Point[matOfPoint.size()];
        for(int i=0; i<matOfPoint.size(); i++){
            pointthree[i] = centerCal(matOfPoint.get(i));
        }
        return pointthree;
    }

    // 转换为中心点
    private Point centerCal(MatOfPoint matOfPoint){
        double centerx=0,centery=0;
        MatOfPoint2f mat2f = new MatOfPoint2f( matOfPoint.toArray() );
        RotatedRect rect = Imgproc.minAreaRect( mat2f );
        Point vertices[] = new Point[4];
        rect.points(vertices);
        centerx = ((vertices[0].x + vertices[1].x)/2 + (vertices[2].x + vertices[3].x)/2)/2;
        centery =  ((vertices[0].y + vertices[1].y)/2 + (vertices[2].y + vertices[3].y)/2)/2;
        Point point= new Point(centerx,centery);
        return point;
    }


    // 寻找二维码轮廓点
    private List<MatOfPoint> markContour(Mat src_gray, List<MatOfPoint> contours, Mat hierarchy) {
        List<MatOfPoint> markContours = new ArrayList<>();
        for (int i = 0; i< contours.size(); i++ ) {
            MatOfPoint2f newMtx = new MatOfPoint2f(contours.get(i).toArray() );
            RotatedRect rotRect = Imgproc.minAreaRect( newMtx );
            double w = rotRect.size.width;
            double h = rotRect.size.height;
            double rate =  Math.max(w, h)/Math.min(w, h) ;
            //长短轴比小于1.3,总面积大于60
            if (rate < 1.3 && w < src_gray.cols()/4 && h< src_gray.rows()/4 && Imgproc.contourArea(contours.get(i))>60) {
                //计算层数,二维码角框有五层轮廓(有说六层),这里不计自己这一层,有4个以上子轮廓则标记这一点
                double[] ds = hierarchy.get(0, i);
                if (ds != null && ds.length>3){
                    int count =0;
                    if (ds[3] == -1){/**最外层轮廓排除*/
                        continue;
                    }
                    //计算所有子轮廓数量
                    while ((int) ds[2] !=-1){
                        ++count;
                        ds = hierarchy.get(0 ,(int) ds[2]);
                    }
                    if (count >= 4){
                        markContours.add(contours.get(i));
                    }
                }
            }
        }
        return markContours;
    }

    // 测试打印图片
    private  void printImg(String name, Mat img){
        if(isDebug) {
            String path = String.format("%s/%s", System.getProperty("user.dir"), name);
            System.out.println("out:" + path);
            Imgcodecs.imwrite(path, img);
        }
    }

    /**
     * Mat转换成BufferedImage
     *
     * @param matrix        要转换的Mat
     * @param fileExtension 格式为 ".jpg", ".png", etc
     * @return
     */
    public static BufferedImage mat2BufImg(Mat matrix, String fileExtension) {
        // convert the matrix into a matrix of bytes appropriate for
        // this file extension
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode(fileExtension, matrix, mob);
        // convert the "matrix of bytes" into a byte array
        byte[] byteArray = mob.toArray();
        BufferedImage bufImage = null;
        try {
            InputStream in = new ByteArrayInputStream(byteArray);
            bufImage = ImageIO.read(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufImage;
    }

    /**
     * BufferedImage转换成Mat
     *
     * @param original
     *            要转换的BufferedImage
     * @param imgType
     *            bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
     * @param matType
     *            转换成mat的type 如 CvType.CV_8UC3
     */
    public static Mat bufImg2Mat (BufferedImage original, int imgType, int matType) {
        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }
        // Don't convert if it already has correct type
        if (original.getType() != imgType) {
            // Create a buffered image
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);
            // Draw the image onto the new buffer
            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
            } finally {
                g.dispose();
            }
        }
        DataBufferByte dbi = (DataBufferByte) original.getRaster().getDataBuffer();
        byte[] pixels = dbi.getData();
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
        mat.put(0, 0, pixels);
        return mat;
    }

    /**
     * 解析读取二维码
     * 先使用ZXING二维码识别,若失败,使用OPENCV自带的二维码识别
     * 个人测试,两者的识别率差不多,都不尽人意,但一起使用还是可以略微提高一点识别率,毕竟实现算法不一样
     * 若还要其它的识别,类似Zbar,都可以集成进来
     *
     * @param qrCodePath 二维码图片路径
     * @return 成功返回二维码识别结果,失败返回null
     * @throws Exception
     */
    public static String decodeQRcode(String qrCodePath){
        String qrCodeText = null;
        try {
            BufferedImage image = ImageIO.read(new File(qrCodePath));
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
            Map<DecodeHintType, Object> hints = new HashMap();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            //如果是二维码注释掉
            //hints.put(DecodeHintType.PURE_BARCODE, BarcodeFormat.DATA_MATRIX);
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);
            qrCodeText = result.getText();
        } catch (Exception e) {
            qrCodeText = new QRCodeDetector().detectAndDecode(Imgcodecs.imread(qrCodePath, 1));
        }
        return qrCodeText;
    }

    /*public static void main(String[] args) {
        Point[] points =  new OpenCVQrCodePosition().getPosition(OpenCVCommon.filePath);
        if(points == null) {
            System.out.println("可能不包含二维码:"+OpenCVCommon.filePath);
            return;
        }
        for (int i = 0; i < points.length; i++) {
            Point p = points[i];
            System.out.println("点" + i + ": " + "(" + p.x + "," + p.y + ")");
        }
        QRCodeDetector detector = new QRCodeDetector();
        String path = String.format("%s/%s", System.getProperty("user.dir"), "cutRect.jpg");
        System.out.println("读取二维码:"+path);
        String qrCodeText = decodeQRcode(path);
        System.out.println("二维码内容:"+ qrCodeText);
    }*/
}
/**
 *
 * 图像识别文字区域
 * main
 *  	Mat src = Imgcodecs.imread(OpenCVCommon.filePath ,1);
 *      OpenCVUtil.imgCorrection(src);
 */
@Component
public class OpenCVUtil {

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	public static Mat imgCorrection(Mat srcImage) {
		// 二值化
		Mat binary = ImgBinarization(srcImage);
		// 膨胀与腐蚀
		Mat preprocess = preprocess(binary);
		// 查找和筛选文字区域
		List<RotatedRect> rects = findTextRegion(preprocess) ;
		//将获取到的矩形根据面积倒序  或 将被包含和重复的去掉
		Mat correction = correction(rects,srcImage);
		return correction;
	}
	/**
	 * 倾斜矫正
	 * @param rects
	 */
	public static Mat correction(List<RotatedRect> rects,Mat srcImage) {
		double degree = 0;
		double degreeCount = 0;
		for(int i = 0; i < rects.size();i++){
			if(rects.get(i).angle >= -90 && rects.get(i).angle < -45){
				degree = rects.get(i).angle;
				if(rects.get(i).angle != 0){
					degree += 90;
				}
			}
			if(rects.get(i).angle > -45 && rects.get(i).angle <= 0){
				degree = rects.get(i).angle;
			}
			if(rects.get(i).angle <= 90 && rects.get(i).angle > 45){
				degree = rects.get(i).angle;
				if(rects.get(i).angle != 0){
					degree -= 90;
				}
			}
			if(rects.get(i).angle < 45 && rects.get(i).angle >= 0){
				degree = rects.get(i).angle;
			}
			if(degree > -5 && degree < 5){
				degreeCount += degree;
			}

		}
		if(degreeCount != 0){
			// 获取平均水平度数
			degree = degreeCount/rects.size();
		}
		Point center = new Point(srcImage.cols() / 2, srcImage.rows() / 2);
		Mat rotm = Imgproc.getRotationMatrix2D(center, degree, 1.0);    //获取仿射变换矩阵
		Mat dst = new Mat();
		Imgproc.warpAffine(srcImage, dst, rotm, srcImage.size(), Imgproc.INTER_LINEAR, 0, new Scalar(255, 255, 255));    // 进行图像旋转操作
		return dst;
	}

	/**
	 * 根据二值化图片进行膨胀与腐蚀
	 * @author MaChao
	 * @time 2019-9-29
	 */
	public static Mat preprocess(Mat binary){
		Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20, 4));
		Mat element2 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 1));
		Mat dilate1 = new Mat();
		Imgproc.dilate(binary, dilate1, element2);

		Mat erode1 = new Mat();
		Imgproc.erode(dilate1, erode1, element1);
		Mat dilate2 = new Mat();
		Imgproc.dilate(erode1, dilate2, element2);
		return dilate2;
	}

	public static Mat ImgBinarization(Mat srcImage){
		Mat gray_image = null;
		try {
			gray_image = new Mat(srcImage.height(), srcImage.width(), CvType.CV_8UC1);
			Imgproc.cvtColor(srcImage,gray_image,Imgproc.COLOR_RGB2GRAY);
		} catch (Exception e) {
			gray_image = srcImage.clone();
			gray_image.convertTo(gray_image, CvType.CV_8UC1);
			System.out.println("原文异常,已处理...");
		}
		Mat thresh_image = new Mat(srcImage.height(), srcImage.width(), CvType.CV_8UC1);
		Imgproc.threshold(gray_image, thresh_image,100, 255, Imgproc.THRESH_BINARY);
		return thresh_image;
	}


	/**
	 * 文字区域
	 * @author MaChao
	 * @time 2019-12-3
	 */
	public static List<RotatedRect> findTextRegion(Mat img)
	{
		List<RotatedRect> rects = new ArrayList();
		//1.查找轮廓
		List<MatOfPoint> contours = new ArrayList();
		Mat hierarchy = new Mat();
		Imgproc.findContours(img, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
		int img_width = img.width();
		int img_height = img.height();
		int size = contours.size();
		//2.筛选那些面积小的
		for (int i = 0; i < size; i++){
			double area = Imgproc.contourArea(contours.get(i));
			if (area < 1000)
				continue;
			//轮廓近似,作用较小,approxPolyDP函数有待研究
			double epsilon = 0.001*Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true);
			MatOfPoint2f approxCurve = new MatOfPoint2f();
			Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(i).toArray()), approxCurve, epsilon, true);

			//找到最小矩形,该矩形可能有方向
			RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
			//计算高和宽
			int m_width = rect.boundingRect().width;
			int m_height = rect.boundingRect().height;

			//筛选那些太细的矩形,留下扁的
            /*if (m_width < m_height)
                continue;
            if(img_width == rect.boundingRect().br().x)
                continue;
            if(img_height == rect.boundingRect().br().y)
                continue;*/
			//符合条件的rect添加到rects集合中
			rects.add(rect);
		}
		System.out.println(rects);
		return rects;
	}
}
/**
 * @author zyw
 * @version 1.0
 * @date 2022-02-10 15:55
 * 二维码定位
 */
@Slf4j
@Component
public class QRCodeToolsUtils {

    /**
     *
     * @Title: deEncodeByPath
     * @Description: 替换原图片里面的二维码
     * @param @param filePath
     * @param @param newPath    设定文件
     * @return void    返回类型
     * @throws
     */
    public  Integer deEncodeByPath(String filePath) {

        //String originalURL = null;
        try {
            BufferedImage readImage = ImageIO.read(new File(filePath));
            LuminanceSource source = new BufferedImageLuminanceSource(readImage);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");

            //如果是二维码注释掉
            //hints.put(DecodeHintType.PURE_BARCODE, BarcodeFormat.DATA_MATRIX);
            Result result = null;
            result = new MultiFormatReader().decode(binaryBitmap, hints);

            //originalURL = result.getText();
            // 解码
            ResultPoint[] resultPoint = result.getResultPoints();
            /*System.out.println("原二维码里面的url:" + originalURL + ",\npoints1: " + resultPoint[0] + ",\npoints2: " + resultPoint[1] + ",\npoints2: "
                    + resultPoint[2] + ",\npoints2: " + resultPoint[3]);*/

            // 获得二维码坐标
            float point1X = resultPoint[0].getX();
            float point1Y = resultPoint[0].getY();
            float point2X = resultPoint[1].getX();
            float point2Y = resultPoint[1].getY();
            float point3X = resultPoint[2].getX();
            float point3Y = resultPoint[2].getY();
            float point4X = resultPoint[3].getX();
            float point4Y = resultPoint[3].getY();
            System.out.println(point1X+"-"+point1Y+"-"+point2X+"-"+point2Y+"-"+point3X+"-"+point3Y+"-"+point4X+"-"+point4Y);
            if(point1X > 150 && point1Y > 150){
                return 1;
            }
            if(point1X > 150 && point1Y < 150){
                return 2;
            }
            if(point1X < 150 && point1Y < 150){
                return 3;
            }
            if(point1X < 150 && point1Y > 150){
                return 4;
            }

            // 替换二维码的图片文件路径
           /* BufferedImage writeFile = ImageIO.read(new File(newPath));

            // 宽高
            final int w = (int) Math
                    .sqrt(Math.abs(point1X - point2X) * Math.abs(point1X - point2X) + Math.abs(point1Y - point2Y) * Math.abs(point1Y - point2Y))
                    + 12 * (7 - 1);
            final int h = w;

            Hashtable<EncodeHintType, Object> hints2 = new Hashtable<EncodeHintType, Object>();
            hints2.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints2.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            hints2.put(EncodeHintType.MARGIN, 1);

            Graphics2D graphics = readImage.createGraphics();
            //此处,偏移,会有定位问题
            int x = Math.round(point1X) - 36;
            int y = Math.round(point2Y) - 36;

            // 开始合并绘制图片
            graphics.drawImage(writeFile, x, y, w, h, null);
            // logo边框大小
            graphics.setStroke(new BasicStroke(2));
            // //logo边框颜色
            graphics.setColor(Color.WHITE);
            graphics.drawRect(x, y, w, h);
            readImage.flush();
            graphics.dispose();*/

            // 打印替换后的图片
            // NewImageUtils.generateWaterFile(readImage, "F:\\image\\save.jpg");
        }

        catch (IOException e) {
            log.error("资源读取失败" + e.getMessage());
            e.printStackTrace();
        }
        catch (NotFoundException e) {
            log.error("读取图片二维码坐标前发生异常:" + e.getMessage());
            e.printStackTrace();
        }  catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /*public static void main(String[] args) {
        QRCodeToolsUtils qr = new QRCodeToolsUtils();
        qr.deEncodeByPath("E:\\java\\idea\\data\\spring\\boot\\QRCode\\code\\1.jpg", "E:\\java\\idea\\data\\spring\\boot\\QRCode\\code\\1.jpg");
    }*/
}

@SpringBootApplication
public class IdentificationApplication {

    public static void main(String[] args) {
        SpringApplication.run(IdentificationApplication.class, args);
    }

}

  1. lib
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值