3.x矢量二维码之个性化绘制

一灰灰blogQuickMedia约 6296 字大约 21 分钟

本片文章将主要介绍矢量二维码(svg格式)的绘制样式使用示例,如何将二维码中的黑色/白色矩形(即码元)替换为更多丰富的图形图案

关于二维码的各元素介绍,请查看 3.x使用实例#二维码各元素说明

1. 几何绘制样式

以下所有实例,可以再源码中获取

0.前置准备

在实际使用时,添加pom依赖,一些术语层级的理解请参看: 3.x二维码基本使用姿势

基本测试

public class BasicGenTest {
    protected String prefix = "/tmp";
    protected static final String msg = "http://weixin.qq.com/r/FS9waAPEg178rUcL93oH";

    @Before
    public void init() {
        if (OSUtil.isWinOS()) {
            prefix = "d://quick-media";
        }
    }
}

1. 矩形二维码

最常规的黑白矩形二维码,也是默认的绘制样式,主要是通过设置 DrawOptions#DrawStyle 来指定具体的二维码样式

@Test
public void rect() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300)
            .newDrawOptions()
            .setDrawStyle(DrawStyle.RECT)
            .complete()
            .asFile(prefix  + "/rect.svg");
    System.out.println(ans);
}

注意上面的实现姿势,设置DrawOptions时,一般的方式是:

  • newDrawOptions() 表示开始进入DrawOptions的配置
  • xxx : 具体的参数配置
  • complete(): 表示DrawOptions配置完成

当然除了上面这种设置方式,也提供了更便捷的配置设置,可以直接省略掉上面的 newDrawOptionscomplete

下面的实现实际与上面的是等价的

public void rectV2() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300)
            .setDrawStyle(DrawStyle.RECT)
            .asFile(prefix  + "/rect.svg");
    System.out.println(ans);
}

说明

  • 上面两种方式如何选择?
  • 当配置参数较多时,推荐使用第一种方式,将DrawOptions相关的配置,都放在一起;阅读管理更方便
  • 当配置参数较小时,使用便捷的方式则会使整体用起来、看起来更简单

2. 圆角矩形

与上面的区别在于 DrawStyle 的设置不同,其他没有什么区别

DrawStyle.ROUND_RECT

public void roundRect() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.ROUND_RECT).asFile(prefix + "/roundRect.svg");
    System.out.println(ans);
}

3. 小矩形

DrawStyle.MINI_RECT

public void miniRect() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.MINI_RECT).asFile(prefix + "/miniRect.svg");
    System.out.println(ans);
}

4. 三角形

DrawStyle.TRIANGLE

public void triangle() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.TRIANGLE).asFile(prefix + "/triangle.svg");
    System.out.println(ans);
}

5. 五边形

DrawStyle.DIAMOND

public void diamond() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.DIAMOND).asFile(prefix + "/diamond.svg");
    System.out.println(ans);
}

6. 五角星

DrawStyle.STAR

public void star() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setW(300)
            .setDrawStyle(DrawStyle.STAR)
            .setPreColor(Color.RED)
            .build()
            .asFile(prefix + "/star.svg");
    System.out.println(ans);
}

7. 六边形

DrawStyle.HEXAGON

public void hexagon() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setW(300).setDrawStyle(DrawStyle.HEXAGON).asFile(prefix + "/hexagon.svg");
    System.out.println(ans);
}

8. 八边形

DrawStyle.OCTAGON

public void octagon() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setW(300).setDrawStyle(DrawStyle.OCTAGON).asFile(prefix + "/octagon.svg");
    System.out.println(ans);
}

9. 圆

DrawStyle.CIRCLE

public void circle() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.CIRCLE).asFile(prefix + "/circle.svg");
    System.out.println(ans);
}

10. 旋转矩形

DrawStyle.ROTATE_RECT

public void rotateRect() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(300).setDrawStyle(DrawStyle.ROTATE_RECT).asFile(prefix + "/rotateRect.svg");
    System.out.println(ans);
}

11. 渲染图片示例

rectroundRectminiRect
trianglediamondstar
hexagonoctagoncircle
rotateRect--

2. 个性化样式

除了以上内置的几何样式的二维码之外,我们还支持直接通过设置svg资源样式,来实现更酷炫的二维码生成

0. 资源位定义

对于信息点/码元,支持直接使用特殊的资源位进行替换

对于svg而言,直接通过设置symbol标签来引入资源位,因此有必要看一下资源位的定义规则,基本上与模板定义的保持一致;

模板标签定义如下

<symbol id="xxx" viewBox="0 0 1024 1024" type="pre" size="1x1"></symbol>
属性名实例是否必须属性类型说明
idlogosvg属性标签的唯一id
viwBox"0 0 128 128"svg属性svg的视窗
width50svg属性定义资源占用的宽度
height50svg属性定义资源占用的高度
size1x1,2x2模板自有属性定义这个资源,在最终二维码中可以占据的位置,如1个黑色点,2x2的黑色点)
count-1模板自有属性定义这个资源在最终二维码中最多出现次数,-1表示无次数限制;>0则表示为次数上限
miss1-1,2-2模板自有属性定义这个资源未能覆盖的区域
typepre,bg,logo,detect,detect_lt,detect_ld,detect_rt模板自有属性不存在时默认值为pre,用于定义这个资源类型

当然我们在实际使用过程中,对于资源位的指定,并不需要在标签中指明这些属性,更通常的情况是直接设置一个id即可,而size,count,miss等属性,则由代码侧进行设置

1. 统一资源位设置

当所有的信息点/码元,都使用相同的资源位进行渲染时,可以如下使用

public static final String SVG_TAG = "<symbol viewBox=\"0 0 1024 1024\">" +
                        "<path d=\"M194.8 408.4c-21.8 0-40.8-7.5-55.1-21.7-11.9-11.9-20.1-27.9-23.6-46.3-3.1-16.2-2.3-33 2.1-47.5 5.4-17.6 16-30.3 29.7-35.8 1-0.4 1.5-1.4 1.5-2.5-2.2-29.5 9.6-51.9 32.5-61.5 0.5-0.2 0.8-0.5 1.1-0.7 11.7-13.9 26.8-21.5 42.4-21.5 3.4 0 6.9 0.4 10.3 1.1 0.2 0 0.4 0.1 0.6 0.1 0.6 0 1.4-0.2 2-1 10.6-13.6 26.2-21.1 43.8-21.1 7.2 0 14.8 1.2 22.7 3.7 0.2 0.1 0.4 0.1 0.6 0.1 0.4 0 0.8-0.1 1.2-0.3 9.5-5.5 24.4-12.1 41.4-12.1 12.1 0 23.4 3.3 33.5 9.8 0.5 0.3 1 0.4 1.4 0.4 0.4 0 0.7-0.1 1.1-0.2 10.5-4.7 21-7.1 31.2-7.1 11.5 0 22.3 3.1 31.8 9.2 0.5 0.3 1 0.5 1.6 0.5 0.5 0 1.3-0.2 2-0.9 13.8-15.6 31.4-23.8 50.8-23.8 17.3 0 35.7 6.6 54.6 19.7 0.4 0.3 0.8 0.4 1.3 0.4 0.6 0 1.2-0.2 1.7-0.6 10.9-8 22.9-12.2 34.6-12.2 13.1 0 25.8 5.2 36.8 15.2 0.3 0.3 0.9 0.5 1.4 0.5 0.3 0 0.5 0 0.7-0.1 6.9-2 14-3 20.9-3 13.8 0 26.7 3.9 38.4 11.5 0.3 0.2 0.7 0.3 1.1 0.3 0.6 0 1.2-0.2 1.7-0.6 12.3-8.4 23.9-12.7 34.6-12.7 12.4 0 23.3 5.7 30.6 16.1 0.4 0.6 1.2 1 2 1h0.3c4.1-0.5 8.1-0.7 11.9-0.7 16.9 0 29.8 4.8 38.3 14.2 5.2 5.8 11.1 16 9.4 32.1-0.1 1.2 0.8 2.4 2.1 2.7 25.4 5.2 39.5 23.7 36.7 48.2-0.1 1 0.5 2 1.5 2.4 24.4 9.4 33.2 23.7 36.2 34 4.3 14.5 0.5 29.9-11.1 45.9-0.7 1-0.9 2.2-0.5 2.9l0.9 1.8c6.2 13.1 5.2 28.2-2.6 40.6-7.9 12.5-21.4 19.9-36.2 19.9H194.8z\" fill=\"#FFFFFF\" p-id=\"3384\"></path><path d=\"M501.2 149c11.9 0 26.2 4.4 43.3 16.2 3.8 2.6 8.2 3.9 12.6 3.9 4.8 0 9.5-1.5 13.5-4.4 6-4.4 13.9-8.4 22.8-8.4 7.3 0 15.3 2.7 23.4 10 4.1 3.7 9.4 5.6 14.8 5.6 2.1 0 4.2-0.3 6.3-0.9 4.3-1.2 9.6-2.2 15.4-2.2 8.4 0 17.9 2 27.4 8.3 3.7 2.4 7.8 3.6 12 3.6 4.5 0 9.1-1.4 13-4 6.9-4.7 15.5-9.2 23.3-9.2 5.4 0 10.4 2.1 14.2 7.6 4.2 6 11.1 9.4 18.4 9.4 0.9 0 1.7 0 2.6-0.1 3-0.3 6.3-0.6 9.6-0.6 14.7 0 29.9 4.6 27.8 24.3-1.2 11.4 6.7 22 17.9 24.3 11.8 2.4 22.8 9.2 20.9 26.3-1.1 10 4.8 19.6 14.2 23.3 17.3 6.7 36.9 21 16.2 49.4-5.1 7-6.1 16.2-2.1 23.9l0.6 1.2c7 14.9-4.2 31.9-20.6 31.9H194.8c-71 0-73.2-99.4-39.5-112.7 9.2-3.6 14.8-12.8 14-22.6-1.2-15.3 1.8-33.8 20.3-41.6 3.3-1.4 6.3-3.5 8.6-6.2 4.7-5.6 14.2-14.4 27.1-14.4 2 0 4 0.2 6.1 0.7 1.6 0.3 3.2 0.5 4.8 0.5 6.9 0 13.4-3.1 17.7-8.7 5.3-6.8 14.1-13.4 28-13.4 4.9 0 10.5 0.8 16.8 2.8 2.1 0.6 4.3 1 6.5 1 3.9 0 7.8-1 11.2-3 7.4-4.2 18.8-9.4 31.4-9.4 7.4 0 15.2 1.8 22.7 6.6 3.7 2.4 7.9 3.6 12.2 3.6 3.2 0 6.3-0.7 9.3-2 6.2-2.8 14.3-5.4 23-5.4 6.9 0 14.1 1.6 21.1 6.1 3.8 2.4 8.1 3.6 12.3 3.6 6.3 0 12.5-2.6 16.9-7.6 7.9-9 19.6-17.3 35.9-17.3m0-40c-14.1 0-27.5 3.3-39.9 9.9-5.7 3-11.1 6.7-16.1 11-9.5-3.9-19.6-5.9-30.2-5.9-10.2 0-20.6 1.9-31 5.5-11.2-5.5-23.3-8.4-36.2-8.4-17.7 0-33.3 5.5-44.7 11.2-7.2-1.7-14.3-2.5-21.2-2.5-20.3 0-38.7 7.4-52.6 21-1.4-0.1-2.7-0.1-4.1-0.1-20.3 0-39.7 9-54.9 25.4-16.6 8-28.9 21.3-35.6 38.7-3.5 9-5.4 18.8-5.6 29.4-13.8 9.1-24.2 23.8-30 42.5-5.4 17.6-6.4 37.9-2.7 57.2 9.8 51.2 48.4 84.3 98.4 84.3h654.1c21.6 0 41.5-10.9 53.1-29.2 10-15.8 12.4-34.8 6.7-52.3 13.7-23 12.6-42.5 8.8-55.3-3.8-12.7-13.2-29.6-36.8-41.9-1.1-14.4-6.7-27.4-16.5-37.5-6.2-6.4-13.8-11.4-22.5-15-1.7-15.3-8.4-25.9-14.5-32.7-8.6-9.5-24.7-20.8-53.2-20.8-1.6 0-3.2 0-4.8 0.1-10.7-10.5-24.8-16.4-40-16.4-11.9 0-24.1 3.5-36.6 10.4-12.2-5.9-25.6-9-39.1-9-5.8 0-11.6 0.5-17.3 1.6-13-9.3-27.5-14.2-42.6-14.2-12.3 0-24.6 3.3-36.2 9.6-19.1-10.9-37.9-16.6-56.2-16.6z\" fill=\"#200000\" p-id=\"3385\"></path><path d=\"M350 343.9h6.5c3.8 0 7.9-1.7 10.6-4.4 2.6-2.6 4.6-6.9 4.4-10.6-0.2-3.9-1.4-7.9-4.4-10.6-2.9-2.7-6.5-4.4-10.6-4.4H350c-3.8 0-7.9 1.7-10.6 4.4-2.6 2.6-4.6 6.9-4.4 10.6 0.2 3.9 1.4 7.9 4.4 10.6 2.9 2.7 6.5 4.4 10.6 4.4zM224.5 276.3h6.5c3.8 0 7.9-1.7 10.6-4.4 2.6-2.6 4.6-6.9 4.4-10.6-0.2-3.9-1.4-7.9-4.4-10.6-2.9-2.7-6.5-4.4-10.6-4.4h-6.5c-3.8 0-7.9 1.7-10.6 4.4-2.6 2.6-4.6 6.9-4.4 10.6 0.2 3.9 1.4 7.9 4.4 10.6 2.9 2.7 6.5 4.4 10.6 4.4zM469.7 243.4c1.7-1.8 3.5-3.5 5.2-5.3 2.7-2.7 4.4-6.7 4.4-10.6 0.1-2.1-0.4-4-1.3-5.8-0.6-1.9-1.6-3.5-3.1-4.8-2.9-2.6-6.6-4.6-10.6-4.4-4 0.2-7.8 1.5-10.6 4.4-1.7 1.8-3.5 3.5-5.2 5.3-2.7 2.7-4.4 6.7-4.4 10.6-0.1 2.1 0.4 4 1.3 5.8 0.6 1.9 1.6 3.5 3.1 4.8 2.9 2.6 6.6 4.6 10.6 4.4 4-0.2 7.8-1.5 10.6-4.4zM614.9 334.8c2.7 0.6 5.5 1.1 8.2 1.7 4 0.8 8 0.6 11.6-1.5 3.1-1.8 6.1-5.4 6.9-9 0.9-3.8 0.7-8.1-1.5-11.6-2-3.2-5.2-6.1-9-6.9-2.7-0.6-5.5-1.1-8.2-1.7-4-0.8-8-0.6-11.6 1.5-3.1 1.8-6.1 5.4-6.9 9-0.9 3.8-0.7 8.1 1.5 11.6 2.1 3.2 5.2 6.1 9 6.9zM772.9 288.2l5.6-5.6c2.7-2.7 4.4-6.8 4.4-10.6 0-3.7-1.6-8.1-4.4-10.6-2.9-2.6-6.6-4.6-10.6-4.4-4 0.2-7.7 1.5-10.6 4.4l-5.6 5.6c-2.7 2.7-4.4 6.8-4.4 10.6 0 3.7 1.6 8.1 4.4 10.6 2.9 2.6 6.6 4.6 10.6 4.4 4-0.2 7.8-1.6 10.6-4.4z\" fill=\"#333333\" p-id=\"3386\"></path><path d=\"M351.4 895c-11 0-20-9-20-20V588.1c0-11 9-20 20-20h323.2c11 0 20 9 20 20V875c0 11-9 20-20 20H351.4z\" fill=\"#FCFCFC\" p-id=\"3387\"></path><path d=\"M674.6 588.1V875H351.4V588.1h323.2m0-40H351.4c-22.1 0-40 17.9-40 40V875c0 22.1 17.9 40 40 40h323.2c22.1 0 40-17.9 40-40V588.1c0-22.1-17.9-40-40-40z\" fill=\"#200000\" p-id=\"3388\"></path><path d=\"M513.5 825.1c-65.6 0-124.9-10.4-176.2-30.9-48.9-19.6-90.8-48.4-124.4-85.6-62.3-69-95.4-165.4-95.7-278.9 0-5.3 2.1-10.4 5.8-14.2s8.8-5.9 14.2-5.9h752.7c5.3 0 10.4 2.1 14.2 5.9 3.8 3.8 5.9 8.9 5.8 14.2-0.3 113.5-33.3 210-95.7 278.9-33.7 37.2-75.5 66-124.4 85.6-51.4 20.5-110.7 30.9-176.3 30.9z\" fill=\"#FFAA46\" p-id=\"3389\"></path><path d=\"M889.8 429.7c-0.5 207.5-115.4 375.5-376.3 375.5s-375.9-168-376.3-375.5h752.6m0-40H137.1c-10.6 0-20.8 4.2-28.3 11.7-7.5 7.5-11.7 17.7-11.7 28.3 0.3 118.5 35.1 219.6 100.8 292.3 35.7 39.5 80.1 70.1 131.8 90.8 53.7 21.5 115.5 32.4 183.7 32.4s130-10.9 183.7-32.4c51.8-20.7 96.1-51.2 131.8-90.8 65.6-72.6 100.5-173.5 100.8-291.8v-0.6c0.1-22-17.8-39.9-39.9-39.9z m0 80z\" fill=\"#200000\" p-id=\"3390\"></path>" +
                        "</symbol>";


public void drawPreResources() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(500)
            .newDrawOptions()
            .setRenderResource(new QrResource().setSvg(SVG_TAG))
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .asFile(prefix + "/draw_01.svg");
    System.out.println(ans);
}

上面是个相对完整的配置,当然我们也提供了更简洁的使用方式,如省略掉newDrawOptions + complete

public void drawPreResources() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
        .setSize(500)
        .setDrawResource(new QrResource().setSvg(SVG_TAG))
        .setDrawStyle(DrawStyle.SVG)
        .asFile(prefix + "/draw_01.svg");
    System.out.println(ans);
}


// DrawStyle也可以直接省略
public void drawPreResourcesV2() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(500).setDrawResource(SVG_TAG)
          .asFile(prefix + "/draw_011.svg");
  System.out.println(ans);
}

注意观察上面的 drawPreResourcesV2,省略了设置 DrawStyle, 通常这是没有什么问题的,会自动根据存在自定义的svg资源从而设置全局的绘制样式,但是并不能100%保证这个是没有问题的;因此更推荐的是显示设置这个参数

其次就是资源信息的指定

  • new QrResource()

外部指定的特殊资源,都是放在这个类中,其除了指定资源之外,还可以指定这个资源对应的绘制样式,颜色等其他选项;在只需要指定资源信息时,可以直接省略掉这个类的显示创建,直接通过 setDrawResource(string) 达到同样的效果

2. 同时设置信息点,背景点

上面是设置全局的信息点,我们也支持设置背景点,即将原来的白色小方块用我们自定义的资源进行替换,如下

public void drawBgPreResources() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
            .setSize(500)
            .setDetectSpecial(true)
            .newDrawOptions()
            .setRenderResource(
                    // 第一个资源为信息点图 (即二维码中的黑色区域)
                    new QrResource().setSvg(
                            "<symbol id=\"pre\" viewBox=\"0 0 1024 1024\" width=\"200\" height=\"200\">" +
                                    "<path d=\"M512 512m-160 0a160 160 0 1 0 320 0 160 160 0 1 0-320 0Z\" fill=\"#000000\" p-id=\"6725\"></path>" +
                                    "</symbol>"),
                    // 第二个资源为背景点图 (即二维码中的白色区域)
                    new QrResource().setSvg(
                            "<symbol id=\"bg\" viewBox=\"0 0 1024 1024\" width=\"200\" height=\"200\">" +
                                    "<path d=\"M512 512m-160 0a160 160 0 1 0 320 0 160 160 0 1 0-320 0Z\" fill=\"#eeeeee\" p-id=\"6725\"></path>" +
                                    "</symbol>"))
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .asFile(prefix + "/draw_02.svg");
    System.out.println(ans);
}

上面的写法也是可以进行简化的;有兴趣的小伙伴可以尝试一下

3. 同时支持多种绘制样式

当我们希望一个二维码中存在多种绘制样式时,也可以非常简单的实现,如下面的示例中,二维码中将存在矩形,圆、三角形、五角星

public void drawSpecialResourceV3() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
            .setSize(500)
            .setDetectSpecial(true)
            .newDrawOptions()
            .newRenderResource(new QrResource().setDrawStyle(DrawStyle.RECT))
            .addResource(new QrResource().setDrawStyle(DrawStyle.CIRCLE))
            .addResource(new QrResource().setDrawStyle(DrawStyle.TRIANGLE))
            .addResource(new QrResource().setDrawStyle(DrawStyle.STAR))
            .build()
            .over()
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .asFile(prefix + "/draw_03.svg");
    System.out.println(ans);
}

自定义资源和内部提供的几何样式也可以混搭使用,指定不同资源的占位,指定资源出现的次数等

public void drawSpecialResourceV4() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
            .setSize(500)
            .setDetectSpecial(true)
            .newDrawOptions()
            // 1x1 对应的资源信息
            .newRenderResource(new QrResource().setSvg("<symbol id=\"earth\" viewBox=\"0 0 24 24\"><rect x=\"0\" y=\"0\" width=\"24\" height=\"24\" fill=\"#ff0000\"></rect></symbol>"))
            .addResource(new QrResource().setDrawStyle(DrawStyle.STAR))
            .addResource(new QrResource().setDrawStyle(DrawStyle.TRIANGLE))
            .build()
            // 2x2 对应的资源信息
            .createSource(2, 2, new QrResource().setDrawStyle(DrawStyle.CIRCLE).setDrawColor(Color.RED))
            // 指定文字出现最多只出现3次
            .addResource(new QrResource().setDrawStyle(DrawStyle.TXT).setTxtMode(TxtMode.ORDER).setText("小灰灰").setFontStyle(Font.BOLD).setDrawColor(Color.BLUE), 3)
            .build()
            .over()
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .asFile(prefix + "/draw_04.svg");
    System.out.println(ans);
}

上面的drawSpecialResourceV4这个示例非常有代表性,每个资源位除了代替1x1的码元之外,还可以用于渲染MxN的码元,其主要使用姿势在于访问方法createSource()时,前面两个参数就是这个资源位占据的宽高

至于资源位的本身描述信息,如空缺的位置,出现的次数,字体相关的设置,则都是在 QrResource 类中

一个MxN位置的资源,可以是多种类型的,通过addResource()进行添加相同大小的资源信息,最终渲染时默认是随机的方式进行挑选,当一个资源位设置完毕之后,请显示调用build表示结束;所有的资源位通过显示调用over表示设置完成

4. 十字格式资源位渲染示例

默认的资源表示的完全替换 MxN 大小的码元信息;但是如十字架这种资源信息,它是存在空缺的,四个角都是空白的,如果直接渲染3x3的码元,会导致最终的二维码信息缺失

对于这种场景,则会使用到资源位的miss参数,来指定缺省的坐标,如十字格式的资源,缺省坐标为

  • (0,0), (2,0), (0,2), (2,2)
  • 那么对应的配置为 0-0,2-0,0-2,2-2

具体的使用实例如下

public void drawSpecialResourceV5() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
            .setSize(500)
            .setDetectSpecial(true)
            .newDrawOptions()
            .newRenderResource(new QrResource().setDrawStyle(DrawStyle.STAR).setDrawColor(Color.RED))
            .build()
            // 开始设置一个 w x h 区域的资源
            .createSource(3, 3, new QrResource().setSvg(
                    "<symbol id=\"ten\" viewBox=\"0 0 1024 1024\">" +
                            "<path d=\"M128 416h768v192H128z\" fill=\"#ee0000\" p-id=\"2440\"></path>" +
                            "<path d=\"M896 640H128a32 32 0 0 1-32-32v-192a32 32 0 0 1 32-32h768a32 32 0 0 1 32 32v192a32 32 0 0 1-32 32zM160 576h704v-128H160z\" fill=\"#ee0000\" p-id=\"2441\"></path>" +
                            "<path d=\"M416 896V128h192v768z\" fill=\"#ee0000\" p-id=\"2442\"></path>" +
                            "<path d=\"M608 928h-192a32 32 0 0 1-32-32V128a32 32 0 0 1 32-32h192a32 32 0 0 1 32 32v768a32 32 0 0 1-32 32z m-160-64h128V160h-128z\" fill=\"#ee0000\" p-id=\"2443\"></path>" +
                            "</symbol>"))
            // 十字架资源,指定缺省的坐标
            .setMiss("0-0,2-0,0-2,2-2")
            .build()
            .over()
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .asFile(prefix + "/draw_05.svg");
    System.out.println(ans);
}

再给一个更复杂点的十字 + 旗子的实例,其中还包含了指定渲染次数,要求全匹配

  • 对于这个全匹配的理解,
    • 如十字资源没有设置这个,那么允许十字资源的四个角出现star
    • 而flag设置了这个,则旗帜的杆子所在的区域,不能出现star
/**
 * 十字闪亮星星
 */
private static final String BLING_STAR_SVG = "<symbol id=\"ten2\" viewBox=\"0 0 1024 1024\">" +
        "<path d=\"M387.84208 408.812665q-1.009414-1.009414-7.065898-9.589433t-13.122382-19.178866-14.131796-20.18828-11.103554-14.636503q-7.065898-10.09414-3.028242-14.131796t10.09414 2.018828q3.028242 3.028242 10.598847 9.084726t16.150624 12.112968 16.150624 12.112968 11.608261 9.084726q15.14121 13.122382 21.197694 7.065898 3.028242-3.028242 8.075312-6.561191t11.103554-5.551777q10.09414-5.04707 12.112968-23.216522 0-2.018828 4.542363-26.244764t9.589433-58.041304 12.112968-73.182514 12.112968-74.696635 9.589433-61.069546 5.551777-31.796541q2.018828-18.169452 8.075312-19.178866t9.084726 19.178866q1.009414 7.065898 4.542363 32.301248t9.084726 60.564839 11.608261 74.191928 10.598847 72.677807 8.075312 56.527183 4.542363 26.749471q2.018828 6.056484 3.028242 12.617675t6.056484 8.580019q10.09414 4.037656 18.169452 10.09414 12.112968 6.056484 19.178866 0 2.018828-1.009414 10.598847-7.570605t19.178866-14.636503 20.18828-15.14121 13.627089-10.09414q8.075312-6.056484 11.103554-5.04707t0 5.04707q-1.009414 3.028242-8.580019 12.617675t-16.150624 20.692987-15.645917 21.197694l-9.084726 14.131796q-9.084726 12.112968-3.028242 18.169452 3.028242 3.028242 5.551777 7.065898t5.551777 10.09414q6.056484 13.122382 30.28242 17.160038 5.04707 1.009414 28.768299 4.037656t57.536597 8.075312 73.182514 10.598847 73.182514 11.103554 57.536597 9.084726 27.758885 3.532949q12.112968 2.018828 10.598847 9.084726t-10.598847 8.075312q-3.028242 1.009414-28.263592 4.542363t-61.069546 9.589433-77.22017 12.617675-77.724877 12.112968-60.564839 9.589433-25.23535 4.037656q-5.04707 1.009414-9.589433 2.523535t-7.570605 6.561191l-6.056484 12.112968q-4.037656 8.075312-7.065898 10.09414-2.018828 3.028242-3.532949 6.561191t3.532949 10.598847q3.028242 4.037656 9.589433 12.617675t14.636503 19.683573 15.645917 20.18828 9.589433 12.112968q5.04707 8.075312 1.514121 9.084726t-9.589433-4.037656q-4.037656-2.018828-13.627089-8.580019t-20.18828-14.636503-20.18828-14.636503-12.617675-8.580019q-8.075312-9.084726-14.131796-3.028242-3.028242 3.028242-7.570605 4.542363t-8.580019 4.542363q-3.028242 2.018828-6.561191 6.056484t-5.551777 13.122382q0 2.018828-3.532949 27.758885t-8.580019 62.583667-12.112968 79.238998-12.112968 80.248412-9.589433 64.602495-4.542363 31.796541q-2.018828 17.160038-7.065898 14.131796t-7.065898-16.150624q-1.009414-5.04707-4.542363-31.291834t-9.589433-64.602495-13.627089-80.753119-13.627089-79.743705-10.09414-62.583667-4.037656-28.263592q-1.009414-14.131796-9.084726-18.169452-10.09414-4.037656-15.14121-8.075312-5.04707-2.018828-11.608261-1.514121t-8.580019 2.523535q-1.009414 1.009414-11.103554 8.580019t-21.702401 15.645917-21.702401 16.150624-13.122382 9.084726q-3.028242 3.028242-9.084726 4.037656t0-7.065898q3.028242-4.037656 11.608261-15.645917t17.664745-24.225936 16.655331-23.216522 10.598847-13.627089q4.037656-5.04707-0.504707-12.112968t-8.580019-14.131796-11.103554-8.075312-14.131796-3.028242q-2.018828-1.009414-25.740057-4.542363t-58.041304-9.084726-73.687221-12.112968-74.696635-11.608261-61.069546-9.589433-30.787127-5.551777q-16.150624-2.018828-20.692987-9.084726t20.692987-10.09414q9.084726-1.009414 36.843611-5.551777t63.593081-9.589433 76.210756-11.103554 74.191928-11.103554 56.527183-8.580019 23.721229-3.532949q5.04707-1.009414 8.580019-1.514121t6.561191-4.542363q2.018828-5.04707 4.542363-9.084726t4.542363-8.075312q6.056484-8.075312 0-14.131796z\" p-id=\"3411\" fill=\"#ee0000\"></path>" +
        "</symbol>";
/**
 * 旗帜
 */
private static final String FLAG_SVG = "<symbol id=\"flag\" viewBox=\"0 0 1024 1024\">" +
        "<path d=\"M854.016 140.288V583.68s-182.272 80.384-318.976 0-364.544 0-364.544 0V140.288s182.272-80.384 341.504 0c107.008 53.76 342.016 0 342.016 0z\" fill=\"#EFB4BF\" p-id=\"2768\"></path>" +
        "<path d=\"M885.248 103.936c-7.168-5.632-16.896-7.68-26.112-5.632-64 14.848-248.32 45.056-329.728 2.56-131.584-69.12-274.944-36.352-340.992-14.848V38.4c0-16.896-13.824-30.72-30.72-30.72s-30.72 13.824-30.72 30.72V988.16c0 16.896 13.824 30.72 30.72 30.72s30.72-13.824 30.72-30.72v-362.496c50.176-15.872 226.816-64 334.336 2.048 52.224 32.256 110.08 43.008 163.328 43.008 101.376 0 187.392-38.912 193.024-41.472 10.752-5.12 17.92-16.384 17.92-28.16V128c0-9.216-4.608-18.432-11.776-24.064z m-49.664 477.184c-47.616 17.408-179.712 56.32-281.088-5.632-52.736-32.256-115.712-43.008-176.128-43.008-72.704 0-141.824 15.36-183.808 27.648V149.504c48.128-17.92 185.344-57.344 306.176 6.144 92.16 48.128 259.584 24.576 334.848 10.752v414.72z\" fill=\"#C9062C\" p-id=\"2769\"></path>" +
        "</symbol>";

@Test
public void drawSpecialResourceV6() throws Exception {
    boolean ans = QrCodeGenV3.of(msg)
            .setSize(500)
            .newDrawOptions()
            .newRenderResource(new QrResource().setDrawStyle(DrawStyle.STAR).setDrawColor(Color.RED))
            .build()
            // 开始设置一个 w x h 区域的资源
            .createSource(3, 3)
            .addResource(BLING_STAR_SVG)
            // 十字架资源,指定缺省的坐标
            .setMiss("0-0,2-0,0-2,2-2")
            .build()
            // 添加红旗的资源,最多只出现3次
            .createSource(1, 2)
            .addResource(FLAG_SVG, 3).setMiss(0, 1).setFullMatch() // fullMatch 表示全匹配,空白的地方必须是空白,不能为码元
            .build()
            .createSource(2, 4, FLAG_SVG).setMiss("0-2,0-3,1-2,1-3").setFullMatch()
            .build()
            .over()
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .newDetectOptions()
            .setSpecial(true)
            .setInColor(ColorUtil.int2color(0xffee0000))
            .setOutColor(ColorUtil.int2color(0xffdd0000))
            .complete()
            .asFile(prefix + "/draw_06.svg");
    System.out.println(ans);
}

5. 全资源-吃豆人实例

接下来我们再看一个所有信息点都根据传入的资源进行替换的案例,一个吃豆人的二维码

public void symbolCdr() throws Exception {
    boolean svg = QrCodeGenV3.of(msg).setW(500)
            .newDrawOptions()
            .setDrawStyle(DrawStyle.SVG)
            .newRenderResource(new QrResource().setSvg(" <symbol id=\"symbol_1R\" viewBox=\"0 0 50 50\">\n" +
                    "        <circle cx=\"25\" cy=\"25\" r=\"11.5\" style=\"fill: #F98E00\"/>\n" +
                    "    </symbol>")).addResource(new QrResource().setSvg("<symbol id=\"symbol_1X\" viewBox=\"0 0 50 50\">\n" +
                    "        <path d=\"M42.82,21.81C42.82,11.98,34.84,4,25,4S7.19,11.98,7.19,21.81L5.5,44l8.03-4.37L19.3,46l5.7-6.37L30.7,46  l5.78-6.37L44.5,44L42.82,21.81z M18.46,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03s5.76,2.7,5.76,6.03  C24.22,24.48,21.64,27.18,18.46,27.18z M31.54,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03  c3.18,0,5.76,2.7,5.76,6.03C37.3,24.48,34.72,27.18,31.54,27.18z\"\n" +
                    "              style=\"fill: #F98E00\"/>\n" +
                    "        <ellipse cx=\"20.76\" cy=\"22.13\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "        <ellipse cx=\"33.51\" cy=\"21.8\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "    </symbol>")).addResource(new QrResource().setSvg("<symbol id=\"symbol_1W\" viewBox=\"0 0 50 50\">\n" +
                    "        <path d=\"M42.82,21.81C42.82,11.98,34.84,4,25,4S7.19,11.98,7.19,21.81L5.5,44l8.03-4.37L19.3,46l5.7-6.37L30.7,46  l5.78-6.37L44.5,44L42.82,21.81z M18.46,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03s5.76,2.7,5.76,6.03  C24.22,24.48,21.64,27.18,18.46,27.18z M31.54,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03  c3.18,0,5.76,2.7,5.76,6.03C37.3,24.48,34.72,27.18,31.54,27.18z\"\n" +
                    "              style=\"fill: #40C4ED\"/>\n" +
                    "        <ellipse cx=\"18.63\" cy=\"22.66\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "        <ellipse cx=\"31.37\" cy=\"22.34\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "    </symbol>")).addResource(new QrResource().setSvg("<symbol id=\"symbol_1V\" viewBox=\"0 0 50 50\">\n" +
                    "        <path d=\"M42.82,21.81C42.82,11.98,34.84,4,25,4S7.19,11.98,7.19,21.81L5.5,44l8.03-4.37L19.3,46l5.7-6.37L30.7,46  l5.78-6.37L44.5,44L42.82,21.81z M18.46,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03s5.76,2.7,5.76,6.03  C24.22,24.48,21.64,27.18,18.46,27.18z M31.54,27.18c-3.18,0-5.76-2.7-5.76-6.03c0-3.33,2.58-6.03,5.76-6.03  c3.18,0,5.76,2.7,5.76,6.03C37.3,24.48,34.72,27.18,31.54,27.18z\"\n" +
                    "              style=\"fill: #7BB72E\"/>\n" +
                    "        <ellipse cx=\"16.63\" cy=\"22.06\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "        <ellipse cx=\"29.37\" cy=\"21.74\" rx=\"2.02\" ry=\"2.4\" style=\"fill: #555555\"/>\n" +
                    "    </symbol>")).build()
            .createSource(2, 1, new QrResource().setSvg("<symbol id=\"symbol_1T\" viewBox=\"0 0 100 50\">\n" +
                    "        <line x1=\"17\" y1=\"25\" x2=\"83\" y2=\"25\"\n" +
                    "              style=\"fill: none; stroke: #333333; stroke-width: 20; stroke-linecap: round; stroke-miterlimit: 10\"/>\n" +
                    "    </symbol>")).addResource(new QrResource().setSvg(" <symbol id=\"symbol_1U\" viewBox=\"0 0 100 50\">\n" +
                    "        <circle cx=\"25\" cy=\"25\" r=\"11.5\" style=\"fill: #F98E00\"/>\n" +
                    "        <circle cx=\"75\" cy=\"25\" r=\"11.5\" style=\"fill: #F98E00\"/>\n" +
                    "    </symbol>")).build()
            .createSource(1, 3, new QrResource().setSvg("<symbol id=\"symbol_1S\" viewBox=\"0 0 50 150\">\n" +
                    "    <line x1=\"25\" y1=\"20\" x2=\"25\" y2=\"130\"\n" +
                    "              style=\"fill: none; stroke: #333333; stroke-width: 20; stroke-linecap: round; stroke-miterlimit: 10\"/>\n" +
                    "    </symbol>")).build().over()
            .complete()
            .newDetectOptions()
            .setLt(new QrResource().setSvg("<symbol id=\"detect_lt\" viewBox=\"0 0 49 49\">\n" +
                    "        <path d=\"M45.5,42.34c0,1.75-1.38,3.16-3.08,3.16H6.59c-1.7,0-3.09-1.42-3.09-3.16V6.66c0-1.75,1.38-3.16,3.09-3.16h35.83c1.7,0,3.08,1.42,3.08,3.16V42.34z\"\n" +
                    "              style=\"fill: none; stroke: #333333; stroke-width: 7; stroke-linecap: round; stroke-miterlimit: 10\"/>\n" +
                    "        <path d=\"M35,31c0,2.21-1.79,4-4,4H18c-2.21,0-4-1.79-4-4V18c0-2.21,1.79-4,4-4h13c2.21,0,4,1.79,4,4V31z\"\n" +
                    "              style=\"fill: #333333\"/>\n" +
                    "    </symbol>"))
            .setLd(new QrResource().setSvg("<symbol id=\"detect_ld\" viewBox=\"0 0 49 49\">\n" +
                    "        <path d=\"M45.5,42.34c0,1.75-1.38,3.16-3.08,3.16H6.59c-1.7,0-3.09-1.42-3.09-3.16V6.66c0-1.75,1.38-3.16,3.09-3.16h35.83c1.7,0,3.08,1.42,3.08,3.16V42.34z\"\n" +
                    "              style=\"fill: none; stroke: #333333; stroke-width: 7; stroke-linecap: round; stroke-miterlimit: 10\"/>\n" +
                    "        <path d=\"M35,31c0,2.21-1.79,4-4,4H18c-2.21,0-4-1.79-4-4V18c0-2.21,1.79-4,4-4h13c2.21,0,4,1.79,4,4V31z\"\n" +
                    "              style=\"fill: #333333\"/>\n" +
                    "    </symbol>"))
            .setRt(new QrResource().setSvg(" <symbol id=\"detect_rt\" viewBox=\"0 0 49 49\">\n" +
                    "        <path d=\"M45.5,42.34c0,1.75-1.38,3.16-3.08,3.16H6.59c-1.7,0-3.09-1.42-3.09-3.16V6.66c0-1.75,1.38-3.16,3.09-3.16h35.83c1.7,0,3.08,1.42,3.08,3.16V42.34z\"\n" +
                    "              style=\"fill: none; stroke: #333333; stroke-width: 7; stroke-linecap: round; stroke-miterlimit: 10\"/>\n" +
                    "        <path d=\"M35,31c0,2.21-1.79,4-4,4H18c-2.21,0-4-1.79-4-4V18c0-2.21,1.79-4,4-4h13c2.21,0,4,1.79,4,4V31z\"\n" +
                    "              style=\"fill: #333333\"/>\n" +
                    "    </symbol>")).complete()
            .build()
            .asFile(prefix + "/吃豆人.svg");
    System.out.println(svg);
}

6. 文字二维码

最后在给一个文字二维码的使用姿势,通常来讲这个有两种使用姿势,一个是文字本身就是一个svg资源信息;一个则是直接传入text文本

public void textQrcode() throws Exception {
    Boolean svg = QrCodeGenV3.of(msg).setW(500)
            .setDetectSpecial(true)
            .newDrawOptions()
            .newRenderResource(new QrResource().setDrawStyle(DrawStyle.STAR))
            .addResource(new QrResource().setDrawStyle(DrawStyle.TRIANGLE))
            .addResource(new QrResource().setDrawStyle(DrawStyle.TXT).setText("小灰"), 6)
            .build()
            .createSource(3, 1)
            .addResource(new QrResource().setSvg("" +
                    "<symbol id=\"txt\" viewBox=\"0 0 3050 1024\">" +
                    "<path d=\"M3047.733168 222.899918c4.052938 25.329568 1.01326 57.751347-2.026418 86.120391-9.119034 137.792686-15.19839 265.453484-28.37026 412.364697-11.145452 118.542169-7.092616 132.726691-30.396678 150.963948-27.357 22.289992-100.309171 16.21094-119.560397 13.171363 15.19839-177.306675 35.462876-343.468404 46.608328-528.880549 3.039678-65.856817 11.145452-121.581746-54.714102-126.647639-61.806617-3.039577-56.740521-2.026317-191.499308-2.026317-128.679431 0-132.732267-1.013158-189.472788-1.013158-32.423198 0-65.859555-7.092312-72.952069-24.316309-4.052938-11.144945-1.01326-34.448197 4.052938-54.71177 3.039678-12.158205 6.079356-24.316309 10.132192-36.474514l143.877766 0c-3.039678 16.21094-5.066096 20.263574-8.105774 31.40862-1.01326 5.065893 0 7.092312 3.039678 7.092312l398.196915 0C3000.111682 149.950891 3042.667072 175.280459 3047.733168 222.899918L3047.733168 222.899918zM2849.141346 328.270826c-3.039678 21.276833-5.066096 47.61956-8.105774 70.92271l-149.957108 0c-4.052938 39.51409-10.132192 80.041339-14.18513 123.608063 51.674424 0 110.441363-1.013158 166.168725-1.013158l-6.079356 69.909451-165.155463 0c-5.066096 48.632719-10.132192 104.357648-17.224808 154.003525l52.687632 0c4.052938-20.263574 7.092616-46.6063 10.132192-70.92271l109.42816 0c-4.052938 36.474514-7.092616 88.146809-20.264486 125.634481-16.211548 49.645877-143.87772 42.553565-227.975342 42.553565-72.952069 0-174.274499 3.039577-213.790212-28.369044-35.462876-27.355885-18.238068-97.265437-10.132192-139.819003l113.481055 0c-3.039678 25.329568-4.052938 53.698612-7.092616 70.92271l61.806646 0c5.066096-47.61956 13.17187-104.357648 18.238068-154.003525l-184.406714 0c3.039678-23.30315 4.052938-45.593142 7.092616-68.896292 60.793458 0 120.573657-1.013158 181.367014-1.013158 5.066096-35.461355 10.132192-82.067656 15.19839-122.594904-25.330582 0-30.396678-1.013158-31.409938 0-7.092616 3.039577-14.18513 11.144945-43.56865 24.316309-39.515712 19.250415-71.93891 23.30315-120.573657 32.421779 4.052938-25.329568 7.092616-51.672194 10.132192-77.001762 45.595068-21.276833 80.044685-52.685454 105.375267-95.239019l101.32237 0c-5.066096 13.171363-10.132192 28.369044-17.224808 44.579984L2849.141266 328.270826zM2231.074875 113.476377c60.793458-8.10547 135.771945 21.276833 127.666171 89.159967-12.158712 102.331331-246.21341 94.225861-218.856308-24.316309C2149.003772 140.832263 2181.426868 120.568588 2231.074875 113.476377L2231.074875 113.476377zM2308.079881 462.010675c3.039678 73.962186-15.19839 150.963948-34.449616 222.899817-19.251226 72.949027-37.489294 139.819003-56.740521 200.609825l-143.877766 0c20.264486-64.843557 39.515712-135.766268 62.819877-208.715295 21.277746-69.909451 49.648006-139.819003 64.846295-204.66256 13.17187-59.777664-22.290904-103.344489-74.978588-111.449959 4.052938-27.355885 5.066096-53.698612 12.158712-74.975445C2228.035197 310.033467 2303.013785 356.639869 2308.079881 462.010675L2308.079881 462.010675zM1880.499458 273.558954l188.459608 0-8.105774 81.054497-901.769094 0c4.052938-24.316309 7.092616-56.738189 10.132192-81.054497l185.419937 0c-4.052938-11.144945-12.158712-34.448197-17.224808-46.6063l137.798423 0 14.18513 46.6063 273.570399 0 34.449616-46.6063 111.454607 0C1903.803622 238.0977 1888.605232 258.361273 1880.499458 273.558954L1880.499458 273.558954zM1703.18528 143.871839l358.68119 0c-3.039678 20.263574-4.052938 41.540407-7.092616 64.843557l-854.14758 0c2.026418-21.276833 5.066096-43.566825 8.105774-64.843557l346.522506 0c3.039678-12.158205 4.052938-23.30315 7.092616-34.448197l146.917437 0C1706.224958 120.568588 1706.224958 131.713634 1703.18528 143.871839L1703.18528 143.871839zM2015.258245 715.305954c9.119034 11.144945 2.026418 51.672194-3.039678 84.094074l-145.904213 0c3.039678-21.276833 4.052938-45.593142 7.092616-68.896292-15.19839 8.10547-15.19839 8.10547-68.899232 32.421779-49.648006 22.289992-54.714102 27.355885-70.925651 32.421779-21.277746 5.065893-27.357 5.065893-77.005007 5.065893-55.727261 0-65.859555-1.013158-73.965329-7.092312-12.158712-9.118628-26.343842-58.764505-34.449616-80.041339l147.93066 0c4.052938 16.21094 6.079356 33.434937 14.18513 50.659035 3.039678 3.039577 4.052938 5.065893 11.145452 4.052735 57.75378-27.355885 98.282651-45.593142 138.811623-62.81724 3.039678-1.013158 39.515712-1.013158 91.190137-1.013158C1986.887984 704.161009 2004.112792 704.161009 2015.258245 715.305954L2015.258245 715.305954zM1712.304314 825.742755l299.914216 0c-3.039678 21.276833-4.052938 37.487672-7.092616 60.790822l-469.122574 0c-65.859555 0-209.737274 8.10547-220.882726-46.6063-8.105774-39.51409 2.026418-94.225861 5.066096-129.687216l138.811647 0c-4.052938 35.461355-9.119034 72.949027-9.119034 102.331331 0 7.092312 4.052938 8.10547 9.119034 11.144945 3.039678 1.013158 6.079356 2.026317 9.119034 2.026317L1712.304273 825.742653zM1961.557402 437.694366c12.158712 35.461355 4.052938 73.962186 0 113.476276s-9.119034 72.949027-14.18513 112.463118l-709.256591 0c16.211548-174.2672-2.026418-279.638006 101.322329-279.638006l284.71586 0 243.173688 0C1908.869718 383.995754 1950.411848 406.285746 1961.557402 437.694366L1961.557402 437.694366zM1821.732519 592.711049c4.052938-37.487672 8.105774-84.094074 13.17187-124.621323-16.211548-7.092312-27.357-13.171363-50.661165-13.171363l-166.168687 0-223.922438 0-4.052938 41.540407 341.456387 0-8.105774 60.790822-338.416716 0c-1.01326 12.158205-1.01326 23.30315-4.052938 35.461355L1821.732433 592.710948zM1156.044561 709.226902l135.771976 0c-3.039678 25.329568-4.052938 51.672194-7.092616 79.02818s-2.026418 58.764505-13.17187 74.975445c-23.304164 31.40862-132.732267 18.237257-135.771945 18.237257C1142.872589 821.69002 1147.938685 761.912356 1156.044561 709.226902L1156.044561 709.226902zM1103.356877 435.667948c20.264486 47.61956 42.55539 94.225861 38.502453 160.082576-11.145452 152.990366-147.930657 263.427066-314.099383 255.321697-144.890979-8.10547-230.00176-88.146809-271.543992-208.715295 30.396678-28.369044 106.388527-22.289992 133.745527 2.026317 11.145452 11.144945 13.17187 23.30315 22.290904 34.448197 27.357 32.421779 67.885973 57.751347 121.586815 60.790822 152.996754 8.10547 227.975342-173.25394 129.692589-271.532536-88.150459-88.146809-281.676185-44.579984-285.729122 97.265437-23.304164 32.421779-73.965329 53.698612-127.666171 40.527249-8.105774-154.003525 75.991747-234.044863 184.406692-279.638006-22.290904-22.289992-38.502453-34.448197-81.057944-66.869975-32.423198-24.316309-49.648006-34.448197-85.110781-66.869975-48.634746-45.593142-55.727261-136.779426-4.052938-186.425303 91.190137 102.331331 212.776952 176.293516 320.178739 265.453484-31.409938-44.579984-86.124041-90.173126-133.745527-133.739951-13.17187-12.158205-39.515712-31.40862-42.55539-44.579984-8.105774-35.461355 38.502453-80.041339 58.766939-93.212702 67.885973 126.647639 168.195143 222.899817 249.252987 336.376194 0 1.013158 1.01326 2.026317 2.026418 3.039577l2.026418 3.039577-2.026418-3.039577c-36.476034-67.883134-82.071103-140.832161-123.613335-209.728453 16.211548-24.316309 40.528972-40.527249 68.899232-52.685454C995.955191 205.67582 1051.682452 317.125779 1103.356877 435.667948L1103.356877 435.667948zM563.308671 246.203068c46.608328 16.21094 24.317323 78.014921 11.145452 121.581746-59.780199 59.777664-96.256233 191.491197-58.766939 299.901579-27.357 35.461355-65.859555 55.724929-101.322329 81.054497 39.515712 48.632719 78.018266 92.199443 117.533979 139.819003l-149.957108 0-72.952069-77.001762c-90.176877 48.632719-189.472788 86.120391-308.020027 109.423541l14.18513-58.764505c85.110781-31.40862 158.06285-73.962186 226.962082-121.581746-35.462876-40.527249-68.899232-78.014921-105.375267-121.581746 19.251226-96.252178 35.462876-191.491197 54.714102-285.717057-85.110781 0-150.970335 14.184522-154.010013-87.133549l169.208358 0 3.039678-15.19768c3.039678-9.118628 4.052938-20.263574 7.092616-32.421779 3.039678-13.171363 6.079356-29.382303 11.145452-47.61956l135.771976 0c-7.092616 31.40862-13.17187 62.81724-21.277746 94.225861C414.364754 245.18991 490.356501 245.18991 563.308671 246.203068L563.308671 246.203068zM444.761433 333.336719l-121.586844 0c-12.158712 55.724929-50.661165 247.216227-50.661165 251.268962 0 0 53.700843 65.856817 64.846295 77.001762 23.304164-21.276833 52.687583-54.71177 54.714102-56.738189C392.07385 601.829678 432.602822 394.127541 444.761433 333.336719z\"></path>" +
                    "</symbol>"), 5)
            .build().over()
            .setDrawStyle(DrawStyle.SVG)
            .complete()
            .build()
            .asFile(prefix + "/txt.svg");
    System.out.println(svg);
}

上面这个case属于文字的混搭,有传入的文本"小灰",限制最多只出现6次,其中每个字符按照顺序依次出现,也可以通过设置TxtMode.RANDOM来设置为随机出现

对于文字的二维码方式,下面再给个经典的千字文的二维码样式

public void textQrCodeV2() throws Exception {
    boolean ans = QrCodeGenV3.of(msg).setSize(500)
            .setDrawResource(new QrResource().setText(QuickQrUtil.DEFAULT_QR_TXT).setTxtMode(TxtMode.ORDER))
            .setQrType(QrType.SVG)
            .setDrawStyle(DrawStyle.TXT)
            .asFile(prefix + "/txtv2.svg");
    System.out.println(ans);
}

7. 渲染图示例

drawPreResourcesdrawBgPreResourcesdrawSpecialResourceV3
drawSpecialResourceV4drawSpecialResourceV5drawSpecialResourceV6
symbolCdrtextQrcodetextQrCodeV2
Loading...