又一年的中秋将至,要怎么样才能蹭一波它的热度呢?作为一个coder,是不是可以用代码写首诗?想法是好,可惜难度有点大,那么就简单点,给自己的二维码上,加个月饼吧
1. logo中加月饼? 在二维码中添加月饼,好像没啥难度,直接网上搜一个二维码生成器,然后找个月饼图,作为logo拍上去,game over
如果仅限于此的话,本文也就没啥意思了,接下来我们看些不一样的东西
2. 拒绝黑白块,满屏二维码 接下来我们使用github上的quick-media:qrcode-plugin
来实现更多有意思的二维码定制
首先引入依赖
1 2 3 4 5 <dependency > <groupId > com.github.liuyueyi.media</groupId > <artifactId > qrcode-plugin</artifactId > <version > 2.6.1</version > </dependency >
接下来我们使用三个月饼图,来生成一张满屏皆是月饼的二维码
要生成上面的二维码也很简单,实现代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 String sourcePrefix = "/Users/user/Documents/qr/" ; QrCodeGenWrapper.of(msg) .setW(500 ) .setH(500 ) .setErrorCorrection(ErrorCorrectionLevel.M) .setDiaphaneityFill(true ) .setDrawBgColor(Color.WHITE) .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE_V2) .setImgResourcesForV2(RenderImgResourcesV2.create() .addSource(1 , 1 ).addImg(sourcePrefix + "00.png" ) .addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ) .build() .addSource(2 , 2 ) .addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() .addSource(3 , 3 ).addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() ) .asFile(sourcePrefix + "/out0.jpg" );
上面虽然生成了一个满屏就是月饼的二维码,但识别是个问题,关键点就是三个码眼(探测图形)
3. 码眼也要绚起来 既然上面的码眼不够优秀,那就替换掉,用自定义的码眼来代替默认生成的,提高识别率
要实现上面的这个二维码,方法也很简单,在前面的基础上,指定一下探测图形即可
1 2 3 4 5 6 .setLTDetectImg(sourcePrefix + "d1.jpg" ) .setLDDetectImg(sourcePrefix + "d2.jpg" ) .setRTDetectImg(sourcePrefix + "d3.jpg" )
其他的设置方式和前面的也没有什么区别,实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 String sourcePrefix = "/Users/user/Documents/qr/" ; QrCodeGenWrapper.of(msg) .setW(500 ) .setH(500 ) .setErrorCorrection(ErrorCorrectionLevel.M) .setDiaphaneityFill(true ) .setDrawBgColor(Color.WHITE) .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE_V2) .setLTDetectImg(sourcePrefix + "d1.jpg" ) .setLDDetectImg(sourcePrefix + "d2.jpg" ) .setRTDetectImg(sourcePrefix + "d3.jpg" ) .setImgResourcesForV2(RenderImgResourcesV2.create() .addSource(1 , 1 ).addImg(sourcePrefix + "00.png" ) .addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ) .build() .addSource(2 , 2 ) .addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() .addSource(3 , 3 ).addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() ) .asFile(sourcePrefix + "/out_d0.jpg" );
4. 印有诗词的二维码 既然最开始说了中秋要用代码写诗来蹭热度,虽然写诗我不行,但是作为一个专职ctrl+c/ctrl+v的coder,抄我可会了,接下来我们把苏轼大大的千古名篇,给印在我们的二维码上
上面这个二维码有点意思了,直接用中文来渲染,要实现也很简单,下面几个简单配置即可
1 2 3 4 5 6 7 8 9 10 String sourcePrefix = "/Users/user/Documents/qr/" ; QrCodeGenWrapper.of(msg) .setDetectSpecial() .setDrawStyle(QrCodeOptions.DrawStyle.TXT) .setQrText("明月几时有把酒问青天不知天上宫阙今夕是何年我欲乘风归去又恐琼楼玉宇高处不胜寒起舞弄清影何似在人间" + "转朱阁低绮户照无眠不应有恨何事长向别时圆人有悲欢离合月有阴晴圆缺此事古难全但愿人长久千里共婵娟" ) .setLogo(sourcePrefix+"/logo2.jpg" ) .setLogoStyle(QrCodeOptions.LogoStyle.ROUND) .setLogoBorderBgColor(Color.GRAY) .asFile(sourcePrefix + "/ft.jpg" );
5. 有诗词,也有月饼的二维码 只有诗词没有月饼不好看;只有月饼没有诗词不够秀,那就合起来,生成一个类似下面的二维码
需要注意的是,上面的包中,并没有提供这种混编的方式,需要我们拉到源码自定义改造一番,重写QrCodeOption.DrawStyle中的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 IMAGE_V2 { @Override public void draw (Graphics2D g2d, int x, int y, int w, int h, BufferedImage img, String txt) { String source = "明月几时有把酒问青天不知天上宫阙今夕是何年我欲乘风归去又恐琼楼玉宇高处不胜寒起舞弄清影何似在人间" + "转朱阁低绮户照无眠不应有恨何事长向别时圆人有悲欢离合月有阴晴圆缺此事古难全但愿人长久千里共婵娟" ; if ("false" .equals(txt)) { if (Math.random() < 0.8f ) { if (Math.random() < 0.6f ) { int offsetX = w / 5 , offsetY = h / 5 ; int width = w - offsetX * 2 , height = h - offsetY * 2 ; g2d.fillRect(x + offsetX, y + offsetY, width, height); return ; } int index = QuickQrUtil.getIndex(); if (index >= source.length()) { int offsetX = w / 5 , offsetY = h / 5 ; int width = w - offsetX * 2 , height = h - offsetY * 2 ; g2d.fillRect(x + offsetX, y + offsetY, width, height); } else { Font oldFont = g2d.getFont(); if (oldFont.getSize() != w) { Font newFont = QuickQrUtil.font(oldFont.getName(), oldFont.getStyle(), w); g2d.setFont(newFont); } g2d.drawString(source.substring(index, index+1 ), x, y + w); g2d.setFont(oldFont); } } else { g2d.drawImage(img.getScaledInstance(w, h, Image.SCALE_SMOOTH), x, y, null ); } } else { g2d.drawImage(img.getScaledInstance(w, h, Image.SCALE_SMOOTH), x, y, null ); } } @Override public boolean expand (DotSize dotSize) { return true ; } }
6. 让二维码动起来 上面的这些都是静态的,接下来我们赋予它动起来的能力,生成一个gif版的二维码,需要我们做的事情也不多,找个gif背景图即可
上面这个动态二维码的生成方式也很简单,基本配置与前面一致,区别在于指定背景gif图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 String sourcePrefix = "/Users/user/Documents/qr/" ; QrCodeGenWrapper.of(msg) .setW(160 ) .setH(160 ) .setErrorCorrection(ErrorCorrectionLevel.M) .setDiaphaneityFill(true ) .setDrawBgColor(Color.WHITE) .setPadding(0 ) .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE_V2) .setDetectSpecial() .setImgResourcesForV2(RenderImgResourcesV2.create() .addSource(1 , 1 ).addImg(sourcePrefix + "00.png" ) .addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ) .build() .addSource(2 , 2 ) .addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() .addSource(3 , 3 ).addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() ) .setLogo(sourcePrefix+"/logo.jpg" ) .setLogoRate(12 ) .setLogoStyle(QrCodeOptions.LogoStyle.ROUND) .setLogoBorderBgColor(Color.GRAY) .setBgImg(sourcePrefix + "/bg4.gif" ) .setBgStyle(QrCodeOptions.BgImgStyle.FILL) .setBgStartX(10 ) .setBgStartY(120 ) .asFile(sourcePrefix + "/out3.gif" ); }
除了上面这种动态之外,还可以实现类似logo的动图效果,如
实现姿势也很简单,借助FtImg
来指定前置的gif图即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 String sourcePrefix = "/Users/user/Documents/qr/" ; QrCodeGenWrapper.of(msg) .setW(500 ) .setH(500 ) .setDiaphaneityFill(true ) .setDrawBgColor(ColorUtil.OFF_WHITE) .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE_V2) .setDetectSpecial() .setImgResourcesForV2(RenderImgResourcesV2.create() .addSource(1 , 1 ).addImg(sourcePrefix + "00.png" ) .addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ) .build() .addSource(2 , 2 ) .addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() .addSource(3 , 3 ).addImg(sourcePrefix + "00.png" ).addImg(sourcePrefix + "01.png" ) .addImg(sourcePrefix + "02.png" , 1 ) .addImg(sourcePrefix + "03.png" ).build() ) .setFtImg("https://b-ssl.duitang.com/uploads/item/201609/14/20160914224309_WNUaE.gif" ) .setFtW(112 ) .setFtH(120 ) .setFtStartX(-194 ) .setFtStartY(-190 ) .asFile(sourcePrefix + "/out_ft1.gif" );
7. 最后的最后 最后声明,本文中所有资源来自网络,如有侵权,联系即删,本文中所有的二维码生成,都是基于开源项目quick-media来生成的, 有兴趣的小伙伴可以尝鲜一下https://github.com/liuyueyi/quick-media ,毕竟月饼节到了,怎么着也得吃个吧
II. 其他 一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
2. 声明 尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
3. 扫描关注 一灰灰blog