2.x使用示例
qrcode-plugin 2.0使用教程
本文中所有示例case,均可在测试用例中获取: QrCodeGenUserGuide.java
1. 功能介绍
大的方面主要分为二维码的生成和解析两块,qrcode-plugin生成二维码的功能上,做了深度的开发定制,目前基本上可以覆盖二维码的各种生成场景
- 支持logo
- 支持logo样式 (圆角logo, 边框, 圆形logo)
- 支持二维码颜色设置
- 支持二维码圆角
- 支持探测图形颜色设置
- 支持探测图形选用图片
- 支持背景图,三种背景样式
- 支持背景图圆角设置
- 支持base64格式的二维码图片
- 支持二维码定制绘制信息样式
- 三角形
- 矩形
- 五边形 (五角星待支持)
- 六边形
- 八边形
- 圆
- 自定义图片
- 文字二维码
- 前置图支持
2. 使用尝鲜
- 环境配置
请直接使用中央仓库引入最新依赖
<!-- https://mvnrepository.com/artifact/com.github.liuyueyi.media/qrcode-plugin -->
<dependency>
<groupId>com.github.liuyueyi.media</groupId>
<artifactId>qrcode-plugin</artifactId>
<version>2.5.6</version>
</dependency>
- 配置介绍
使用qrcode-plugin
插件生成二维码是一个非常简单的事情,通过一些基本的参数来控制输出二维码样式,一个链式调用即可完成
参数说明
二维码图片的基本参数
/**
* 内容
*/
private String msg;
/**
* 输出图片宽
*/
private Integer w;
/**
* 输出图片高
*/
private Integer h;
/**
* 内容编码, default UTF-8
*/
private String code = "utf-8";
/**
* 边框 0 - 4 (0表示无边框)
*/
private Integer padding;
/**
* 容错级别
*/
private ErrorCorrectionLevel errorCorrection = ErrorCorrectionLevel.H;
/**
* 输出二维码图片类型
*/
private String picType = "png";
探测图形(二维码左上,右上,左下三个方框)的参数配置
/**
* 外面的方框颜色
*/
private Color outColor;
/**
* 内部方框颜色
*/
private Color inColor;
/**
* 探测图形,优先级高于颜色的定制(即存在图片时,用图片绘制探测图形)
*/
private BufferedImage detectImg;
/**
* 左上角的探测图形
*/
private BufferedImage detectImgLT;
/**
* 右上角的探测图形
*/
private BufferedImage detectImgRT;
/**
* 左下角的探测图形
*/
private BufferedImage detectImgLD;
/**
* true 表示探测图形单独处理
* false 表示探测图形的样式更随二维码的主样式
*/
private Boolean special;
二维码图形(就是普通二维码中的黑点)绘制参数:
/**
* 着色颜色,即二维码点阵中为1的区域绘制颜色,也就是常见二维码中的黑色小方块
*/
private Color preColor;
/**
* 背景颜色, 即二维码点阵中为0的区域绘制颜色,也就是常见二维码中的白色小方块
*/
private Color bgColor;
/**
* 透明度填充,如绘制二维码的图片中存在透明区域,若这个参数为true,则会用bgColor填充透明的区域;若为false,则透明区域依旧是透明的
*/
private boolean diaphaneityFill;
/**
* 背景图,即二维码点阵中为0的区域渲染图片,也就是常见二维码中的白色小方块
*/
private BufferedImage bgImg;
/**
* 绘制样式: 矩形,三角,原点,五边形,六边形,八边形,图片
*/
private DrawStyle drawStyle;
/**
* true 时表示支持对相邻的着色点进行合并处理 (即用一个大图来绘制相邻的两个着色点)
* <p>
* 说明: 三角形样式关闭该选项,因为留白过多,对识别有影响
*/
private boolean enableScale;
/**
* 渲染图
*/
private Map<DotSize, BufferedImage> imgMapper;
/**
* 生成二维码的图片样式,一般来讲不推荐使用圆形,默认为normal
*/
private ImgStyle qrStyle;
/**
* 圆角的弧度,默认为 1 / 8
*/
private Float cornerRadius;
/**
* 生成文字二维码时的候字符池
*/
private String text;
/**
* 生成文字二维码时的字体
*/
private String fontName;
/**
* 字体样式
*
* {@link Font#PLAIN} 0
* {@link Font#BOLD} 1
* {@link Font#ITALIC} 2
*/
private int fontStyle;
logo样式配置
/**
* logo 图片
*/
private BufferedImage logo;
/**
* logo 样式 (圆角,普通,圆)
*/
private LogoStyle logoStyle;
/**
* logo 占二维码的比例
*/
private int rate;
/**
* true 表示有边框,
* false 表示无边框
*/
private boolean border;
/**
* 边框颜色
*/
private Color borderColor;
/**
* 外围边框颜色
*/
private Color outerBorderColor;
/**
* 用于设置logo的透明度
*/
private Float opacity;
背景图配置
/**
* 背景图样式
*/
private ImgStyle imgStyle;
/**
* 圆角弧度,默认为宽高中较小值的 1/8
*/
private float radius;
/**
* 背景图(静态二维码时使用)
*/
private BufferedImage bgImg;
/**
* 动态背景图(动态二维码生成时使用)
*/
private GifDecoder gifDecoder;
/**
* 背景图宽
*/
private int bgW;
/**
* 背景图高
*/
private int bgH;
/**
* 背景图样式(全覆盖,指定位置填充,背景图渲染)
*/
private BgImgStyle bgImgStyle;
/**
* if {@link #bgImgStyle} == QrCodeOptions.BgImgStyle.OVERRIDE,
* 用于设置二维码的透明度
*/
private float opacity;
/**
* if {@link #bgImgStyle} == QrCodeOptions.BgImgStyle.FILL
* <p>
* 用于设置二维码的绘制在背景图上的x坐标
*/
private int startX;
/**
* if {@link #bgImgStyle} == QrCodeOptions.BgImgStyle.FILL
* <p>
* 用于设置二维码的绘制在背景图上的y坐标
*/
private int startY;
前置图配置
/**
* 前置图
*/
private BufferedImage ftImg;
/**
* 背景图样式
*/
private ImgStyle imgStyle;
/**
* 圆角弧度,默认为宽高中较小值的 1/8
*/
private Float radius;
/**
* 动态前置图
*/
private GifDecoder gifDecoder;
/**
* 背景图宽
*/
private int ftW;
/**
* 背景图高
*/
private int ftH;
/**
* 用于设置二维码的绘制在前置图上的x坐标
*/
private int startX;
/**
* 用于设置二维码的绘制在前置图上的y坐标
*/
private int startY;
/**
* 填充色
*/
private Color fillColor;
接下来我们通过一系列的实例代码,来演示如何生成各种酷炫的二维码
a. 基本二维码
生成一个最常见的最普通的二维码,并保存到qr.png
文件,一行代码即可
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
// 生成二维码,并输出为qr.png图片
boolean ans = QrCodeGenWrapper.of(msg).asFile("qr.png");
v2.5.2 新增二维码圆角设置
/**
* 默认的二维码生成
*/
@Test
public void defaultQr_corner() {
try {
// 生成二维码,并输出为qr.png图片
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(500)
.setPadding(3)
// 圆角二维码, 不建议使用圆形的二维码,会导致生成的二维码不可用
.setQrStyle(QrCodeOptions.ImgStyle.ROUND)
// 圆角弧度默认是宽高的 1/8, 可以根据需要自行设置
.setQrCornerRadiusRate(0.125F)
.setPicType("png")
.asFile("/tmp/dq_corner1.png");
} catch (Exception e) {
e.printStackTrace();
}
}
输出圆角的二维码图片(建议图片右键新标签页打开,可以看到明显的四边圆角)
b. 颜色指定
默认的二维码为白底黑块,如果我希望生成白底蓝块(探测图形外青内红)的二维码,可以如下使用
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(300)
// 探测图形特殊处理
.setDetectSpecial()
// 定位点(探测图形)外边颜色
.setDetectOutColor(Color.CYAN)
// 定位点内部颜色
.setDetectInColor(Color.RED)
// 二维码着色点
.setDrawPreColor(Color.BLUE)
// 二维码背景图
.setDrawBgColor(0xffffffff)
.asFile("/tmp/cqr.png");
c. 带logo二维码生成
logo目前支持两种样式,一个是圆角logo,一个是直接原图不做处理;下面是一个简单的圆角logo,并带上边框的实例
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
// 这里的图片地址,支持网络图片,本地相对路劲图片,本地绝对路径图片
String logo = "https://static.oschina.net/uploads/user/283/566591_100.jpeg";
boolean ans = QrCodeGenWrapper.of(msg)
.setLogo(logo)
.setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
.setLogoBgColor(0xfffefefe)
.setLogoBorderBgColor(0xffc7c7c7)
.setLogoBorder(true)
.asFile("/tmp/lqr3.png");
下图展示了四张带logo的二维码
- 原始logo
- 直角带logo背景色
- 圆角带logo背景色
- 圆角带logo背景,边框
说明:2.4.2版本优化了logo的锯齿严重的问题
v2.4版本新增圆形logo
/**
* 带外边框的圆形logo
*/
@Test
public void logoQr4() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String logo = "logo.jpg";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(400)
.setLogo(logo)
// 圆形logo支持
.setLogoStyle(QrCodeOptions.LogoStyle.CIRCLE)
.setLogoBgColor(0xfffefefe)
.setLogoBorderBgColor(0xffc7c7c7)
.setLogoBorder(true)
.asFile("/tmp/lqr4.png");
}catch (Exception e) {
e.printStackTrace();
}
}
d. 指定背景图
背景图目前支持三种样式,分别是二维码全覆盖在背景图上,在背景图的自定区间进行绘制二维码,生成透明二维码但使用背景图进行渲染,下面
// 默认属于全覆盖的背景模式,对应下图中图1
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String bg = "http://ww1.sinaimg.cn/large/8154e929gy1g8vho8x6r0j20b40b43yl.jpg";
boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setW(500)
.setBgOpacity(0.5f)
.asFile("/tmp/bqr1.png");
// 指定为填充模式,在背景图的坐标(startX, startY)处绘制二维码(左上角坐标为0,0); 对应下图中的图2
bg = "http://pic.51yuansu.com/pic3/cover/01/07/09/59015a0e53d83_610.jpg";
ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setBgStyle(QrCodeOptions.BgImgStyle.FILL)
.setBgW(500)
.setBgH(500)
.setBgStartX(130)
.setBgStartY(120)
.setW(260)
.setPadding(0)
.setDrawBgColor(0xfff7f7f7)
.asFile("/tmp/bqr2.png");
// 背景渲染方式,用背景图来填充二维码,对应下图中的图3
bg = "http://img1.juimg.com/180517/355855-1P51H3520817.jpg";
ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setBgStyle(QrCodeOptions.BgImgStyle.PENETRATE)
.setBgW(500)
.setBgH(500)
.setW(500)
.asFile("/tmp/bqr3.png");
// 针对第一种背景方式的扩展,二维码前置、后置都可以使用图片替换
String bg = "overbg/bg.jpg";
String cell = "overbg/a.png";
String bgCell = "overbg/b.png";
Boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setW(500)
.setErrorCorrection(ErrorCorrectionLevel.H)
.setBgStyle(QrCodeOptions.BgImgStyle.OVERRIDE)
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.setDrawImg(cell)
.setDrawBgImg(bgCell)
.asFile("/tmp/bqr4.png");
给出一个背景图为文字的二维码输出演示case
@Test
public void bgQrTxt() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
BufferedImage bgImg = GraphicUtil.createImg(500, 500, null);
Graphics2D g2d = GraphicUtil.getG2d(bgImg);
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(0, 0, 500, 500);
Font font = new Font("宋体", Font.BOLD, 500);
g2d.setFont(font);
g2d.setColor(Color.RED);
g2d.drawString("码", 0, 500 - g2d.getFontMetrics().getDescent() / 2);
g2d.dispose();
boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bgImg)
.setBgStyle(QrCodeOptions.BgImgStyle.PENETRATE)
.setBgW(500)
.setBgH(500)
.setW(500)
.asFile("/tmp/bqrTxt.png");
} catch (Exception e) {
e.printStackTrace();
}
}
v2.5.2 支持背景图圆角、圆形设置
@Test
public void bgQr1_corner() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String bg = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2859744156,2204003006&fm=26&gp=0.jpg";
boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setW(500)
.setBgOpacity(0.6f)
// 背景圆角比例
.setBgCornerRadiusRate(0.125f)
.setBgImgStyle(QrCodeOptions.ImgStyle.ROUND)
.asFile("/tmp/bqr1_c1.png");
}catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void bgQr1_circle() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String bg = "http://pic.51yuansu.com/pic3/cover/01/07/09/59015a0e53d83_610.jpg";
boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setBgStyle(QrCodeOptions.BgImgStyle.FILL)
.setBgW(500)
.setBgH(500)
.setBgStartX(130)
.setBgStartY(120)
.setW(260)
.setPadding(0)
.setDrawBgColor(0xfff7f7f7)
.setBgImgStyle(QrCodeOptions.ImgStyle.CIRCLE)
.asFile("/tmp/bqr2_c2.png");
}catch (Exception e) {
e.printStackTrace();
}
}
e. 探测图形样式指定
探测图形,指的是左上角、右上角、左下角的三个”回字“,除了上面介绍到的指定不同的颜色之外,还可以用图片替换
// 指定探测图形为固定图片,输出如下图中图1
QrCodeGenWrapper.of(msg)
.setW(500)
.setDetectImg("detect.png")
.asFile("/tmp/tqr1.png");
// 分别制定三个探测图形,对应三个图片,输出如下图中图2
QrCodeGenWrapper.of(msg)
.setW(500)
.setLTDetectImg("leaf/eye.png")
.setLDDetectImg("jihe/PDP.png")
.setRTDetectImg("love/01.png")
// 这个参数表示探测图形中的透明区域,用二维码背景色填充
.setDiaphaneityFill(true)
.asFile("/tmp/tqr2.png");
v2.4 探测图形新增参数special
- true: 表示探测图形独立绘制,与二维码的绘制样式不同;请注意当设置探测图形img时,这个参数默认为true
- false: 探测图形的渲染和二维码一致
下面两段代码生成分别为下图一二,请注意setDetectSpecial()
设置之后探测图形并不一样了
@Test
public void detectedQr3() {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
try {
QrCodeGenWrapper.of(msg)
.setDrawStyle(QrCodeOptions.DrawStyle.CIRCLE)
.setDrawEnableScale(true)
.asFile("/tmp/tqr3.png");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void detectedQr4() {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
try {
QrCodeGenWrapper.of(msg)
.setDetectSpecial()
.setDrawStyle(QrCodeOptions.DrawStyle.CIRCLE)
.setDrawEnableScale(true)
.asFile("/tmp/tqr4.png");
} catch (Exception e) {
e.printStackTrace();
}
}
f. 几何样式二维码生成
默认的二维码的信息为黑色小方块,本插件提供了其他的几个常见的几何形式支持,如圆点,三角,钻石,六边形,八边形;通过指定DrawStyle参数即可
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(400)
// 支持将临近相同的合并成一个大的圆点
.setDrawEnableScale(true)
.setDrawStyle(QrCodeOptions.DrawStyle.CIRCLE)
.asFile("/tmp/dqr6.png");
v2.4 新增文字二维码
- 指定一串字符串,根据字符串内容生成二维码
@Test
public void fontQr1() {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
int size = 500;
try {
boolean ans = QrCodeGenWrapper.of(msg)
.setW(size)
.setH(size)
// 不指定text时,默认文本为千字文,宋体加粗
.setQrText("我是一灰灰欢迎关注")
.setDetectSpecial()
.setErrorCorrection(ErrorCorrectionLevel.H)
.setDrawStyle(QrCodeOptions.DrawStyle.TXT)
.setPicType("png")
.asFile("/tmp/fontQr1.png");
} catch (Exception e) {
e.printStackTrace();
}
}
v2.4.1 支持文字二维码渲染模式(顺序or随机)
/**
* 文字二维码
*/
@Test
public void fontQr3() {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
try {
boolean ans = QrCodeGenWrapper.of(msg)
.setQrText("欢迎关注一灰灰")
// 指定文字随机渲染方式
.setQrTxtMode(QrCodeOptions.TxtMode.RANDOM)
// true 则探测图形有自己的绘制规则
.setDetectSpecial()
.setErrorCorrection(ErrorCorrectionLevel.H)
.setDrawStyle(QrCodeOptions.DrawStyle.TXT)
// 当相邻的NxN都是黑色小方块时,放大(慎用,因为部分汉子如 `一` 无法友好的填充2x2的方块)
.setDrawEnableScale(true)
.setPicType("png")
.asFile("/tmp/fontQr3.png");
} catch (Exception e) {
e.printStackTrace();
}
}
v2.6.0 新增MINI_RECT样式
@Test
public void miniRectQr() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(200)
// 如果希望探测图形依然是标准的,加上下面这一行
// .setDetectSpecial()
.setDrawStyle(QrCodeOptions.DrawStyle.MINI_RECT)
.asFile(prefix + "/dqr0_1.png");
} catch (Exception e) {
e.printStackTrace();
}
}
g. 图片填充
如果你有一套完整的素材,那么可以考虑用这些素材来生成一个更漂亮的二维码;
比如项目的测试中,给出了两套输出,一个爱心,一个集合图形
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
int size = 500;
// 爱心素材生成的二维码图片,如下图中的图1,请注意我们的二维码背景渲染色指定为透明,最终输出的二维码也是带透明度的png图片,
boolean ans = QrCodeGenWrapper.of(msg)
.setW(size)
.setH(size)
.setErrorCorrection(ErrorCorrectionLevel.M)
.setDrawBgColor(ColorUtil.OPACITY)
.setDetectImg("love/01.png")
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.addImg(1, 1, "love/003_01.png")
.addImg(4, 1, "love/004.png")
.addImg(1, 4, "love/004_02.png")
.asFile("/tmp/imgQr1.png");
// 几何素材生成的二维码图片
ans = QrCodeGenWrapper.of(msg)
.setW(size)
.setH(size)
.setErrorCorrection(ErrorCorrectionLevel.H)
// 因为素材为png透明图,我们这里设置二维码的背景为透明,输出更加优雅
.setDrawBgColor(ColorUtil.OPACITY)
.setDetectImg("jihe/PDP.png")
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.addImg(1, 1, "jihe/a.png")
.addImg(3, 1, "jihe/b.png")
.addImg(1, 3, "jihe/c.png")
.addImg(3, 2, "jihe/e.png")
.addImg(2, 3, "jihe/f.png")
.addImg(2, 2, "jihe/g.png")
.addImg(3, 4, "jihe/h.png")
.setPicType("png")
.asFile("/tmp/imgQr2.png");
// 除了指定二维码的”前置图片“之外,还可以指定”后置图片“
// 注意下图中的图3,其中黑色小点为素材图片,对应二维码中黑色方块;
// 白色小点也是素材图片,对应二维码中的白色方块
ans = QrCodeGenWrapper.of(msg)
.setW(size)
.setH(size)
.setErrorCorrection(ErrorCorrectionLevel.M)
.setDrawBgColor(ColorUtil.OPACITY)
.setDrawBgImg("overbg/b.png")
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.setDrawImg("overbg/a.png")
.asFile("/tmp/imgQr3.png");
使用这种方式,需要稍微注意一下
- 必须指定DrawStyle为图片模式
addImg(row, column, img)
来声明素材对应的应用场景,这个表示当出现一个row行,column列都有信息时,用img来填充setDrawImg
: 如果所有的二维码图片都是一个的话,可以用这个方法替代addImg(1,1,img)
setDrawBgImg
: 设置的是二维码矩阵中为0(即白色小方块)的渲染图片,不是整个二维码的背景图哦setDrawBgColor(ColorUtil.OPACITY)
: 设置二维码绘制背景色为透明,可以充分利用素材图片的透明区域,使显示效果更优雅
下面是一个是quick-media提供的三种样式模板
v2.6.0 图片二维码的支持相同位置的多图随机渲染
@Test
public void imgQr2() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
int size = 500;
boolean ans = QrCodeGenWrapper.of(msg)
.setW(size)
.setH(size)
.setErrorCorrection(ErrorCorrectionLevel.M)
.setDrawBgColor(ColorUtil.OPACITY)
.setDetectImg("love/01.png")
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.addImg(1, 1, "love/001.png")
.addImg(2, 2, "love/003_01.png")
.addImg(2, 2, "love/003_02.png")
.addImg(2, 2, "love/003_03.png")
.addImg(4, 1, "love/004.png")
.addImg(1, 4, "love/004_02.png")
.asFile(prefix + "/imgQr2.png");
} catch (Exception e) {
e.printStackTrace();
}
}
h. 动态二维码
接下来介绍一下动态二维码的生成,和背景图的使用姿势基本上完全以往,唯一的区别就是背景图为gif动图
// 全覆盖模式,指定二维码的透明度(如下图左)
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String bg = "http://ww1.sinaimg.cn/large/8154e929gy1g8pq78mcgrg20dw0boaja.gif";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(500)
.setBgImg(bg)
.setBgOpacity(0.6f)
.setPicType("gif")
.asFile("/tmp/gifQr1.gif");
// 填充模式,在背景图的指定位置上绘制二维码,属于常见的一种动图模式(如下图中)
bg = "http://ww1.sinaimg.cn/large/8154e929gy1g8qe2iv0evg20xc0irn68.gif";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(400)
.setBgImg(bg)
.setBgStyle(QrCodeOptions.BgImgStyle.FILL)
.setBgStartX(20)
.setBgStartY(137)
.setPicType("gif")
.asFile("/tmp/gifQr2.gif");
// 背景渲染模式,直接用背景图来填充二维码信息,因此可以实现炫酷的二维码(如下图右)
bg = "http://ww1.sinaimg.cn/large/8154e929gy1g8w7wj6qvsg20oy0io4dt.gif";
boolean ans = QrCodeGenWrapper.of(msg)
.setBgImg(bg)
.setBgW(500)
.setBgH(500)
.setBgStyle(QrCodeOptions.BgImgStyle.PENETRATE)
.setW(500)
.asFile("/tmp/gifQr3.gif");
i. 前置图
qrcode v2.5.3
提供前置图功能,支持在二维码上层覆盖图片,基本使用姿势如下(项目源码的test中,通过QrCodeGenUserGuide#ft1
查看)
/**
* 前置图测试,对应下图中的第一张
*/
@Test
public void ft1() {
try {
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
String ft = "ft/ft_1.png";
boolean ans = QrCodeGenWrapper.of(msg)
.setDetectImg("eye3.png")
.setW(1340)
.setH(1340)
// 下面ft开头的都是前置图设置
.setFtImg(ft)
// 二维码小于前置图,因此剩余的地方用白色填充
.setFtFillColor(Color.WHITE)
// 二维码在前置图中的x,y偏移
.setFtStartX(100)
.setFtStartY(130)
.asFile("/tmp/ft1.png");
} catch (Exception e) {
e.printStackTrace();
}
}
借助前置图,可以实现某些小伙伴希望在二维码的周边加文字的需求,一种方法是设计一个固定文字的模板,直接作为前置图,使用上面的姿势
也可以自己来生成动态的文字前置图,下面是一个具体实现case
/**
* 在二维码周边添加文字的示例,对应上图中间的那个
*/
@Test
public void ft2() {
// 创建一个文字的前置图
BufferedImage ftImg = GraphicUtil.createImg(500, 600, null);
Graphics2D g2d = GraphicUtil.getG2d(ftImg);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 500, 500, 500);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font(null, Font.PLAIN, 22));
g2d.drawString("欢迎关注《一灰灰Blog》", 140, 550);
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
try {
boolean ans = QrCodeGenWrapper.of(msg)
.setW(500)
.setH(500)
.setDetectImg("eye3.png")
.setFtImg(ftImg)
.setFtFillColor(Color.WHITE)
.asFile("/tmp/ft2.png");
} catch (Exception e) {
e.printStackTrace();
}
}
如果希望文字动态,那么更推荐的是结合image-plugin
来使用,比如我可以实现文字垂直输出
/**
* 在二维码周边添加文字的实例,借助 image-plugins 来实现,能更简单的满足UI大佬的设计需求
* 对应上图中右边的那个
*/
@Test
public void ft3() {
try {
// 二维码
int qrSize = 460;
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
BufferedImage qrImg = QrCodeGenWrapper.of(msg)
.setW(qrSize)
.setH(qrSize)
.setDetectImg("eye3.png")
.setFtFillColor(Color.WHITE)
.asBufferedImage();
ImgCell qrCell = ImgCell.builder().img(qrImg).x(20).y(20).build();
// 修饰文字
TextCell textCell = TextCell.builder().font(new Font("宋体", Font.BOLD, 22))
.color(Color.BLACK)
.drawStyle(ImgCreateOptions.DrawStyle.VERTICAL_LEFT)
.alignStyle(ImgCreateOptions.AlignStyle.CENTER)
.startX(540)
.startY(0)
.endX(540)
.endY(500)
.text("欢迎关注<一灰灰Blog>")
.build();
BufferedImage out = ImgMergeWrapper.merge(Arrays.asList(qrCell, textCell), 600, 500, Color.WHITE);
ImageIO.write(out, "jpg", new File("/tmp/ft3.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
}
前置渲染模板还支持动态gif,如添加一个动态的logo
public void preGif() {
String pre = "https://iknow-pic.cdn.bcebos.com/f9dcd100baa1cd11dec1529bbd12c8fcc3ce2d11";
try {
// 二维码
int qrSize = 320;
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
QrCodeGenWrapper.of(msg)
.setW(qrSize)
.setH(qrSize)
.setDrawPreColor(0xff73a7f5)
// .setDrawStyle(QrCodeOptions.DrawStyle.CIRCLE)
.setDrawEnableScale(true)
.setFtImg(pre)
.setFtStartX(0)
.setFtStartY(-25)
.setFtFillColor(Color.WHITE)
.asFile("/tmp/ft_1.gif");
} catch (Exception e) {
e.printStackTrace();
}
}
对应的二维码如下:
j. 综合
上面的几种case,是可以组合使用的,最后给一个综合的"求关注"动态二维码的生成实例
String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";
// 网络动图背景
String bg = "http://ww1.sinaimg.cn/large/8154e929gy1g8w9jsxwtdg20pz08zwr8.gif";
// 本地logo
String logo = "logo.jpg";
boolean ans = QrCodeGenWrapper.of(msg)
.setW(500)
.setDrawBgColor(ColorUtil.OPACITY)
.setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
.setDetectImg("jihe/PDP.png")
.addImg(1, 1, "jihe/a.png")
.addImg(3, 1, "jihe/b.png")
.addImg(1, 3, "jihe/c.png")
.addImg(3, 2, "jihe/e.png")
.addImg(2, 3, "jihe/f.png")
.addImg(2, 2, "jihe/g.png")
.addImg(3, 4, "jihe/h.png")
.setPadding(1)
.setErrorCorrection(ErrorCorrectionLevel.H)
.setLogo(logo)
.setLogoBorder(true)
.setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
.setLogoBgColor(0xfffefefe)
.setLogoBorderBgColor(0xffc7c7c7)
.setBgImg(bg)
.setBgW(1870)
.setBgH(646)
.setBgStyle(QrCodeOptions.BgImgStyle.FILL)
.setBgStartX(690)
.setBgStartY(20)
.setBgOpacity(0.9f)
.setPicType("gif")
.asFile("/tmp/gifQr4.gif");