有段时间没有写博客了,不知道是因为工作的原因还是懒了...

程序员还得以写代码为生,so~进入主题吧

公司是做广告服务的,运转模式一句话就是:在车内设备上播放广告主投放的广告,并获取收益,现在有个需求是,要统计广告主投放的广告里面的二维码的扫码量,进行数据分析,为后面人物画像做准备,因多种事业环境因素,让广告主提供统计数据或者提供链接给我们,我们生成二维码等,根本不太可能,所以,只能自己撸启袖子干!

我疏导了下流程,如下:

1.广告审核的时候,判断图片是否包含二维码

2.包含二维码的图片,对原图片里面二维码进行识别并定位

3.获取原图片里二维码的信息和坐标信息(x,y,w,h),并保存起来

4.开发一个接口,这个接口可以理解为新二维码的链接路径

5.根据坐标使用上面接口如(www.abc?taskId=10&imei=2ej3dd)生成新二维码并推送到设备

6.设备获取推送的包含二维码的图片并根据后台分发的坐标信息生成新的二维码

7.设备根据坐标和其他需要携带的参数生成新二维码

8.用户扫码跳转到接口路径,接口获得相关参数记录扫码量并重定向到原图片里面二维码路径

至此,大功告成!

一个东西的技术实现,都是站在前人的肩膀上去累积,优化,总结的,我大概在网上看了下,貌似没有人遇到这种需求,参考了opencv java版本的代码,毕竟不是做图像识别的,这方面的知识有限,所以用了zxing实现.于是自己硬着头皮上,基本实现了我们的业务需求,但,二维码的坐标识别还是有些许的差别,还是把代码分享出来,起抛砖引玉的作用,同时,也希望大家能够在这个基础上进行优化...

以下为代码片段

先加入maven依赖:

        <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.3.3</version></dependency>

下面为完整java代码:

package com.bpb.qrcode;import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;import javax.imageio.ImageIO;import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import lombok.extern.slf4j.Slf4j;@Slf4j
public class QRCodeTools3 {/*** * @Title: deEncodeByPath * @Description: 替换原图片里面的二维码 * @param @param filePath* @param @param newPath    设定文件 * @return void    返回类型 * @throws*/public static void deEncodeByPath(String filePath, String newPath) {// 原图里面二维码的urlString 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");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();// 替换二维码的图片文件路径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();}}public static void main(String[] args) {deEncodeByPath("F:\\image\\zfb.jpg", "F:\\image\\gzh.jpg");}
}

图一是替换之前的二维码图片(支付宝扫码领红包):

图二为需要替换原图二维码的图片(微信公众号)

下图为最后的效果,可以尝试扫扫(支付宝版的微信公众号):

当然,这也只是个雏形,有更好的方式的同学,可以留言一起探讨,并改善...

java二维码定位获取坐标并替换原来二维码相关推荐

  1. Java 百度地图 根据名称获取坐标(经纬度)

    申请百度开放平台KEY(ak) 没申请,随便找了一个 参数说明: region:召回城市 city_limit:区域数据召回限制 这两个参数必须配合使用,city_limit为true时,仅召回reg ...

  2. php蓝奏云解析源码,PHP获取蓝奏云直链解析源码

    PHP获取蓝奏云直链的源码案例 可以用来做api调用到网站做下载 调用方法: 无密码:http://www.yyob.com/lanzou/?url=https://www.lanzous.com/i ...

  3. Revit二次开发_获取视图样式替换

    目的是用于导出视图样板中的图形替换,但Revit中视图样板其实也属于视图,所以对于所有视图都通用. 方法十分简单,视图中的样式替换都可以通过OverrideGraphicSettings读取,要注意的 ...

  4. 飞鹅小票打印机嵌入生成指定小程序页面二维码的解决方案 | 扫普通链接二维码打开小程序示例 | 生成正方形小程序码

    部分朋友不需要打印机的业务,则 忽略有关打印机的部分 即可. 其他有关 微信小程序配置的介绍是通用的!通用的! 生成正方形小程序码,请看 标题一. 扫普通链接生成的二维码打开小程序,请看 标题二. 目 ...

  5. Opencv的使用小教程3——利用轮廓检测实现二维码定位

    Opencv的使用小教程3--利用轮廓检测实现二维码定位 二维码具有什么特征 实现效果 识别二维码的流程 1.预处理图像 2.寻找轮廓 3.通过寻找到的轮廓确定"回"的位置 4.创 ...

  6. opencv4.0.1 qr二维码定位识别源码详解(一)

    一.概述 opencv4.0版本以后,加入了二维码定位解码的功能,其主要功能基于quirc开源库,下载地址GitHub.约1200行代码,识别与定位占了约800行,解码部分不作赘述,直接调用quric ...

  7. OpenCV 二维码定位与识别

    因为二维码本身含有信息,因此可以作为产品的信息载体,如:产品特征.在工业领域常用在产品入库.分拣和包装上.但常常会因为二维码图像污点.光照不均匀以及二维码图像倾斜等原因,使得二维码的识别正确率低,针对 ...

  8. python3 + opencv +pyzbar实时检测二维码 / 定位二维码,并绘制出二维码的框和提取二维码内容

    python3 + opencv +pyzbar实时检测二维码 / 定位二维码,并绘制出二维码的框和提取二维码内容 1 pyzbar二维码检测模块 1.1. pyzbar模块介绍 1.2 pyzbar ...

  9. 微信蓝牙设备开发教程之获取蓝牙设备deviceid和设备二维码(2)

    已推出最新微信硬件jsapi学习笔记 地址 http://www.vxzsk.com/282.html 要想获取设备的deviceid和设备的二维码,必须满足1个条件,设备所属的产品号码product ...

最新文章

  1. Hadoop集群搭建(七:MySQL的安装配置)
  2. R语言获取当前R版本(version)实战
  3. jdk的logging我们Logger.getLogger(xxx)jdk都干了啥
  4. Ulink2 No Ulink Device found 解决办法
  5. django的模板系统过滤器笔记
  6. 消息中间件原理及JMS简介之二
  7. csv 逗号数量不一样_lexin_common系列之CSV
  8. 游戏筑基开发之深度优先搜索算法(C语言)
  9. jquery.event 研究学习之bind篇
  10. c语言输出数组时输出的乱七八糟
  11. 暴力算法-BF(Brute Force)
  12. Zemax自学--2(Zemax软件总览)
  13. linux V4L2子系统——v4l2架构(1)之整体架构
  14. 悟彻菩提真妙理 断魔归本合元神
  15. Python书法碑帖分割(分别以对于汉字命名)
  16. log4j自定义新的级别
  17. MT6737模块编译方法
  18. python利用datetime模块计算时间差
  19. 计算机配置 主板,整套解决方案:I5-3470处理器和什么主板构成计算机配置?
  20. mapbox-gl提升建筑渐变效果(视频)

热门文章

  1. 【java养成】:案例(模拟银行新用户现金业务办理、USB接口程序设计、身份证校验位和身份提取)
  2. 接口返回 ““ 的解决方式
  3. 用户输入金额限制两位小数完美解决,代码可以拿走,留下你的赞,赠人玫瑰,手留余香
  4. 【华为OD机试 2023 B卷 | 100分】 统计射击比赛成绩(C++ Java JavaScript )
  5. 绝密101:import,java,packag的顺序、权限修饰符、类及其组成可用的修饰符
  6. Acute TravelLogic使用教程
  7. 世界杯开幕,boss直聘被骂惨
  8. 谁用foobar?我这里有几个非常酷的Title Formatting!原创
  9. android开发笔记之日期显示格式
  10. 兼容主流浏览器的网页闹钟