Java生成带小图标的二维码-google zxing 工具类

  近期一直忙于开发微信商城项目,应客户要求,要开发个有图标的二维码。经过两次改版,终于实现了该功能(第一次没有小图标,这次才整合好的),如下是完整代码 。

  该代码使用Java7开发,另外使用 core-2.2.jar jar[http://pan.baidu.com/s/1skTwHQ1] 包 。

  1 package com.rick.common.utils;
  2
  3
  4 import java.awt.Color;
  5 import java.awt.Graphics2D;
  6 import java.awt.Image;
  7 import java.awt.geom.AffineTransform;
  8 import java.awt.image.AffineTransformOp;
  9 import java.awt.image.BufferedImage;
 10 import java.io.File;
 11 import java.io.IOException;
 12 import java.util.Date;
 13 import java.util.HashMap;
 14 import java.util.Map;
 15
 16 import javax.imageio.ImageIO;
 17
 18 import com.google.zxing.BarcodeFormat;
 19 import com.google.zxing.EncodeHintType;
 20 import com.google.zxing.MultiFormatWriter;
 21 import com.google.zxing.WriterException;
 22 import com.google.zxing.common.BitMatrix;
 23 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 24
 25 /**
 26  * 二维码生成工具类【带小图标】
 27  * <br> QRCodeUtils 类的提升版本
 28  * @author bxw
 29  * @time 2016-07-17 22:13:45
 30  * @version v1.1
 31  */
 32 public class BarcodeFactory {
 33
 34     /**
 35      * 图片格式定义
 36      * @value Array
 37      */
 38     private static String[] IMAGE_TYPE = {"BMP", "bmp", "jpg", "JPG", "wbmp", "jpeg", "png", "PNG", "JPEG", "WBMP", "GIF", "gif","ICON","icon"};
 39
 40     /**
 41      * 二维码宽度
 42      */
 43     public static final int WIDTH = 260;
 44
 45     /**
 46      * 二维码高度
 47      */
 48     public static final int HEIGHT = 260;
 49
 50     /**
 51      * 图标宽度
 52      */
 53     private static final int IMAGE_WIDTH = 68;
 54     /**
 55      * 图标高度
 56      */
 57     private static final int IMAGE_HEIGHT = 68;
 58     /**
 59      * 底图大小【正方形】
 60      */
 61     private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
 62     /**
 63      * 底图边框
 64      */
 65     private static final int FRAME_WIDTH = 5;
 66
 67     /**
 68      * 二维码写码器
 69      */
 70     private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
 71
 72     /**
 73      * 二维码生成-方法入口
 74      * @param content 内容
 75      * @param width 宽度
 76      * @param height 高度
 77      * @param iconImagePath 图标原路径
 78      * @param qrcodeImagePath 二维码存放路径
 79      * @param hasFiller
 80      *             比例不对时是否需要补白:true为补白; false为不补白
 81      * @return
 82      *         成功:返回输出图片绝对路径;失败:返回null
 83      */
 84     public static String encode(String content, int width, int height,
 85             String iconImagePath, String qrcodeImagePath,boolean hasFiller) {
 86         try {
 87             /**
 88              * 图标格式校验
 89              */
 90             File icon = new File(iconImagePath);
 91             if(!icon.exists()){
 92                 System.err.println("系统找不到图标所在文件 !");
 93                 return null;
 94             }
 95             String iconFileName = icon.getName();
 96             // 得到上传文件的扩展名
 97             String fileExtName = iconFileName.substring(iconFileName.lastIndexOf(".") + 1);
 98             if(!checkIMGType(fileExtName)){
 99                 System.err.println("图标格式有误 !");
100                 return null;
101             }
102
103             if(width<260||height<260){
104                 width = BarcodeFactory.WIDTH;
105                 height = BarcodeFactory.HEIGHT;
106             }
107             ImageIO.write(genBarcode(content, width, height, iconImagePath,hasFiller),
108                     "png", new File(qrcodeImagePath));
109             System.err.println("二维码已生成  "+qrcodeImagePath);
110             return qrcodeImagePath;
111         } catch (IOException e) {
112             System.err.println("图片读取异常 : "+e.getMessage());
113         } catch (WriterException e) {
114             System.err.println("图片输出异常 :"+e.getMessage());
115         }
116         return null;
117     }
118
119     /**
120      * 图片处理方法
121      * @param content
122      * @param width
123      * @param height
124      * @param iconImagePath
125      * @param hasFiller
126      *             比例不对时是否需要补白:true为补白; false为不补白;
127      * @return
128      * @throws WriterException
129      * @throws IOException
130      */
131     private static BufferedImage genBarcode(String content, int width,
132             int height, String iconImagePath,boolean hasFiller) throws WriterException,
133             IOException {
134         // 读取源图像
135         BufferedImage scaleImage = scale(iconImagePath, IMAGE_WIDTH,
136                 IMAGE_HEIGHT, hasFiller);
137         int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
138         for (int i = 0; i < scaleImage.getWidth(); i++) {
139             for (int j = 0; j < scaleImage.getHeight(); j++) {
140                 srcPixels[i][j] = scaleImage.getRGB(i, j);
141             }
142         }
143
144         Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
145         hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
146         hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
147         // 生成二维码
148         BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE,
149                 width, height, hint);
150
151         // 二维矩阵转为一维像素数组
152         int halfW = matrix.getWidth() / 2;
153         int halfH = matrix.getHeight() / 2;
154         int[] pixels = new int[width * height];
155
156         for (int y = 0; y < matrix.getHeight(); y++) {
157             for (int x = 0; x < matrix.getWidth(); x++) {
158                 // 读取图片
159                 if (x > halfW - IMAGE_HALF_WIDTH
160                         && x < halfW + IMAGE_HALF_WIDTH
161                         && y > halfH - IMAGE_HALF_WIDTH
162                         && y < halfH + IMAGE_HALF_WIDTH) {
163                     pixels[y * width + x] = srcPixels[x - halfW
164                             + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
165                 }
166                 // 在图片四周形成边框
167                 else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
168                         && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
169                         && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
170                         + IMAGE_HALF_WIDTH + FRAME_WIDTH)
171                         || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
172                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
173                                 && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
174                                 + IMAGE_HALF_WIDTH + FRAME_WIDTH)
175                         || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
176                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
177                                 && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
178                                 - IMAGE_HALF_WIDTH + FRAME_WIDTH)
179                         || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
180                                 && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
181                                 && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
182                                 + IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
183                     pixels[y * width + x] = 0xfffffff;
184                 } else {
185                     // 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
186                     pixels[y * width + x] = matrix.get(x, y) ? 0xff000000
187                             : 0xfffffff;
188                 }
189             }
190         }
191
192         BufferedImage image = new BufferedImage(width, height,
193                 BufferedImage.TYPE_INT_RGB);
194         image.getRaster().setDataElements(0, 0, width, height, pixels);
195
196         return image;
197     }
198
199     /**
200      * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
201      *
202      * @param iconImagePath
203      *            小图标源文件地址
204      * @param height
205      *            目标高度
206      * @param width
207      *            目标宽度
208      * @param hasFiller
209      *            比例不对时是否需要补白:true为补白; false为不补白;
210      * @throws IOException
211      */
212     private static BufferedImage scale(String iconImagePath, int height,
213             int width, boolean hasFiller) throws IOException {
214         double ratio = 0.0; // 缩放比例
215         File file = new File(iconImagePath);
216         BufferedImage srcImage = ImageIO.read(file);
217         Image destImage = srcImage.getScaledInstance(width, height,
218                 BufferedImage.SCALE_SMOOTH);
219         // 计算比例
220         if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
221             if (srcImage.getHeight() > srcImage.getWidth()) {
222                 ratio = (new Integer(height)).doubleValue()
223                         / srcImage.getHeight();
224             } else {
225                 ratio = (new Integer(width)).doubleValue()
226                         / srcImage.getWidth();
227             }
228             AffineTransformOp op = new AffineTransformOp(
229                     AffineTransform.getScaleInstance(ratio, ratio), null);
230             destImage = op.filter(srcImage, null);
231         }
232         if (hasFiller) {// 补白
233             BufferedImage image = new BufferedImage(width, height,
234                     BufferedImage.TYPE_INT_RGB);
235             Graphics2D graphic = image.createGraphics();
236             graphic.setColor(Color.white);
237             graphic.fillRect(0, 0, width, height);
238             if (width == destImage.getWidth(null))
239                 graphic.drawImage(destImage, 0,
240                         (height - destImage.getHeight(null)) / 2,
241                         destImage.getWidth(null), destImage.getHeight(null),
242                         Color.white, null);
243             else
244                 graphic.drawImage(destImage,
245                         (width - destImage.getWidth(null)) / 2, 0,
246                         destImage.getWidth(null), destImage.getHeight(null),
247                         Color.white, null);
248             graphic.dispose();
249             destImage = image;
250             System.err.println("INFO 图标补白已完成 ");
251         }
252         return (BufferedImage) destImage;
253     }
254
255     /**
256      * 图片格式校验
257      * @param fileExtName
258      * @return
259      */
260     private static boolean checkIMGType(String fileExtName){
261         boolean flag = false;
262         for (String type : IMAGE_TYPE) {
263             //-- 图片格式正确
264             if(type.toLowerCase().equals(fileExtName.toLowerCase())){
265                 flag = true;
266                 break;
267             }
268         }
269         //------------图片格式校验结束
270         return flag;
271     }
272
273     /**
274      * 测试主方法入口
275      * @param args
276      */
277     public static void main(String[] args) {
278         String codeIconPath = "C:/Users/rick/Desktop/1.jpg";
279         String codePath = "C:/Users/rick/Desktop/"+new Date().getTime()+".png";
280
281         /**
282          * 测试方法入口
283          */
284         BarcodeFactory.encode("项目:晚餐定制",300, 300, codeIconPath, codePath,false);
285     }
286 }

  著名: 代码只作为学习用途,谢谢 !

时间: 2024-12-25 21:23:00

Java生成带小图标的二维码-google zxing 工具类的相关文章

二维码的功能、特点及使用Java生成带logo的二维码

二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"."1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集:每个字符占有一定的宽度:具有一定的校验功能等.同时还具有对不同行的信息自动识

Java生成带logo 的二维码

这个工具类主要实现了两点功能: 1. 生成任意文链接的二维码. 2. 在二维码的中间加入图像. 主要实现步骤: 第一步: 导入QR二维码3.0 版本的core包和一张jpg图片(logo). core包下载地址:http://central.maven.org/maven2/com/google/zxing/core/3.0.0/ 第二步: 新建一个Java project.将刚下载的core-3.0.0 jar 添加到项目依赖中. 具体步骤: 第三步: 新建两个类,分别是: BufferedI

java生成带logo的二维码,自定义大小,logo路径取服务器端

package com.qishunet.eaehweb.util; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import jav

Java使用zpxing.jar生成带url的二维码

第一步下载zpxing.jar包,并加载进来(网上有很多类似的jar包,这里小编使用的是谷歌提供的jar) 二维码工具类: package com.zpxing.controller; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRe

微信公众号开发(三)生成带参数的二维码

微信公众号开发之生成带参数的二维码 做微信公众号开发的人员都知道用户海报作为公众号吸引用户是常见的渠道,那么我就说说这个海报的生成. 看了好多公众号发现他们的海报都是大同小异,一个漂亮的背景+自己的头像+专属二维码. 背景就不阐述了,用户的头像可以由公众号开发文档提供的方式获取(根据用户的openId),今天主要讲用户的专属二维码 所谓专属即便是一对一的. 二维码分为两种,临时二维码和永久二维码 /*生成永久二维码*/ public static String getPerpetualQR(St

C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(一)

一.ZXing.Net 源代码地址:http://zxingnet.codeplex.com/ 也可以使用Nuget包管理,添加如图: 说明:ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME.J2SE和Android.现在也有了对应的.Net版本 二.生成二维码 将字符编码时可以指定字符格式:默认为ISO-8859-1英文字符集,但一般移动设备常用UTF-8字符

生成带logo的二维码

一,生成带log的二维码 1)生成的二维码是流返回,或者是直接写到指定文件夹 二,准备资料 1)引入jar包 <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <!-- 二维码生成器 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId&g

Java实现带logo的二维码

Java实现带logo的二维码 二维码应用到生活的各个方面,会用代码实现二维码,我想一定是一项加分的技能.好了,我们来一起实现一下吧. 我们实现的二维码是基于QR Code的标准的,QR Code是由日本Denso公司于1994年研制的一种矩阵二维码符号码,全称是Quick Response Code QR Code:专利公开,支持中文: QR Code与其他二维码相比,具有识读速度快.数据密度大.占用空间小的优势: 纠错能力: L级:约可纠错7%的数据码字 M级:约可纠错15%的数据码字 Q级

微信公众平台功能开发(生成带参数的二维码)

为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送. 目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--100000).两种二维码分别适用于帐号绑定.用户来源统计等场景. 用户扫描带场景值二维码时,可能推送以下两种事件: 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事