Java生成中间logo的二维码

自从开始写博客开始菠菜园的栏目调整了很多次,最终呈现了现在这些分类。但是由于开发的关系,平日很少写关于JAVA的,倒是C语言的笔记还略微多些。其实C语言的应用波波也仅限在硬件芯片中使用,大多数时间用的还是PHP语言。至于C++和QT波波也只是开发了一个杀毒软件,除此之外再无什么项目经验。

为了弥补菠菜园一直以来JAVA方面的缺乏,波波从今天开始在工作之余也会分享一些小的应用源码,以供初学JAVA的朋友们借鉴学习。废话不多说,今天分享利用JAVA开发带logo的二维码。

我们经常在网上看到诸如下图这样的二维码。

Java生成中间logo的二维码

源码DEMO:

  1. package com.luo.wctweb.util;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics2D;
  5. import java.awt.image.BufferedImage;
  6. import java.io.ByteArrayOutputStream;
  7. import java.io.File;
  8. import java.util.Date;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. import javax.imageio.ImageIO;
  12. import javax.servlet.http.HttpServletRequest;
  13. import com.google.zxing.BarcodeFormat;
  14. import com.google.zxing.EncodeHintType;
  15. import com.google.zxing.MultiFormatWriter;
  16. import com.google.zxing.WriterException;
  17. import com.google.zxing.common.BitMatrix;
  18. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  19. import com.lz.lsf.util.Base64;
  20. /**  
  21.  * @Description: (二维码)      
  22.  */
  23. public class ZXingCode
  24. {
  25.     private static final int QRCOLOR = 0xFF000000;   //默认是黑色
  26.     private static final int BGWHITE = 0xFFFFFFFF;   //背景颜色
  27.     public static void main(String[] args) throws WriterException
  28.     {
  29.         try
  30.         {
  31.             getLogoQRCode("https://www.baidu.com/"null"跳转到百度的二维码");
  32.         }
  33.         catch (Exception e)
  34.         {
  35.             e.printStackTrace();
  36.         }
  37.     }
  38.     /**
  39.      * 生成带logo的二维码图片
  40.      * @param qrPic
  41.      * @param logoPic
  42.      */
  43.     public static String getLogoQRCode(String qrUrl,HttpServletRequest request,String productName)
  44.     {
  45. //      String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";
  46.         //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好
  47.         String filePath = "C:/Users/luoguohui/Desktop/78310a55b319ebc4fa3aef658126cffc1f17168f.jpg";  //TODO  
  48.         String content = qrUrl;
  49.         try
  50.         {
  51.             ZXingCode zp = new ZXingCode();
  52.             BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400400, zp.getDecodeHintType());
  53.             return zp.addLogo_QRCode(bim, new File(filePath), new LogoConfig(), productName);
  54.         }
  55.         catch (Exception e)
  56.         {
  57.             e.printStackTrace();
  58.         }
  59.         return null;
  60.     }
  61.     /**
  62.      * 给二维码图片添加Logo
  63.      * @param qrPic
  64.      * @param logoPic
  65.      */
  66.     public String addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName)
  67.     {
  68.         try
  69.         {
  70.             /**
  71.              * 读取二维码图片,并构建绘图对象
  72.              */
  73.             BufferedImage image = bim;
  74.             Graphics2D g = image.createGraphics();
  75.             /**
  76.              * 读取Logo图片
  77.              */
  78.             BufferedImage logo = ImageIO.read(logoPic);
  79.             /**
  80.              * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
  81.              */
  82.             int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null),
  83.                 heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);
  84.             /**
  85.              * logo放在中心
  86.              */
  87.              int x = (image.getWidth() - widthLogo) / 2;
  88.              int y = (image.getHeight() - heightLogo) / 2;
  89.              /**
  90.              * logo放在右下角
  91.              *  int x = (image.getWidth() - widthLogo);
  92.              *  int y = (image.getHeight() - heightLogo);
  93.              */
  94.             //开始绘制图片
  95.             g.drawImage(logo, x, y, widthLogo, heightLogo, null);
  96. //            g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
  97. //            g.setStroke(new BasicStroke(logoConfig.getBorder()));
  98. //            g.setColor(logoConfig.getBorderColor());
  99. //            g.drawRect(x, y, widthLogo, heightLogo);
  100.             g.dispose();
  101.             //把商品名称添加上去,商品名称不要太长哦,这里最多支持两行。太长就会自动截取啦
  102.             if (productName != null && !productName.equals("")) {
  103.                 //新的图片,把带logo的二维码下面加上文字
  104.                 BufferedImage outImage = new BufferedImage(400445, BufferedImage.TYPE_4BYTE_ABGR);
  105.                 Graphics2D outg = outImage.createGraphics();
  106.                 //画二维码到新的面板
  107.                 outg.drawImage(image, 00, image.getWidth(), image.getHeight(), null);
  108.                 //画文字到新的面板
  109.                 outg.setColor(Color.BLACK);
  110.                 outg.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号 
  111.                 int strWidth = outg.getFontMetrics().stringWidth(productName);
  112.                 if (strWidth > 399) {
  113. //                  //长度过长就截取前面部分
  114. //                  outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字
  115.                     //长度过长就换行
  116.                     String productName1 = productName.substring(0, productName.length()/2);
  117.                     String productName2 = productName.substring(productName.length()/2, productName.length());
  118.                     int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
  119.                     int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
  120.                     outg.drawString(productName1, 200  - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );
  121.                     BufferedImage outImage2 = new BufferedImage(400485, BufferedImage.TYPE_4BYTE_ABGR);
  122.                     Graphics2D outg2 = outImage2.createGraphics();
  123.                     outg2.drawImage(outImage, 00, outImage.getWidth(), outImage.getHeight(), null);
  124.                     outg2.setColor(Color.BLACK);
  125.                     outg2.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号 
  126.                     outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
  127.                     outg2.dispose();
  128.                     outImage2.flush();
  129.                     outImage = outImage2;
  130.                 }else {
  131.                     outg.drawString(productName, 200  - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //画文字 
  132.                 }
  133.                 outg.dispose();
  134.                 outImage.flush();
  135.                 image = outImage;
  136.             }
  137.             logo.flush();
  138.             image.flush();
  139.             ByteArrayOutputStream baos = new ByteArrayOutputStream();
  140.             baos.flush();
  141.             ImageIO.write(image, "png", baos);
  142.             //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉
  143.             //可以看到这个方法最终返回的是这个二维码的imageBase64字符串
  144.             //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/>  其中${imageBase64QRCode}对应二维码的imageBase64字符串
  145.             ImageIO.write(image, "png"new File("C:/Users/luoguohui/Desktop/TDC-" + new Date().getTime() + "test.png")); //TODO  
  146.             String imageBase64QRCode =  Base64.byteArrayToBase64(baos.toByteArray());
  147.             baos.close();
  148.             return imageBase64QRCode;
  149.         }
  150.         catch (Exception e)
  151.         {
  152.             e.printStackTrace();
  153.         }
  154.         return null;
  155.     }
  156.     /**
  157.      * 构建初始化二维码
  158.      * @param bm
  159.      * @return
  160.      */
  161.     public BufferedImage fileToBufferedImage(BitMatrix bm)
  162.     {
  163.         BufferedImage image = null;
  164.         try
  165.         {
  166.             int w = bm.getWidth(), h = bm.getHeight();
  167.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  168.             for (int x = 0; x < w; x++)
  169.             {
  170.                 for (int y = 0; y < h; y++)
  171.                 {
  172.                     image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
  173.                 }
  174.             }
  175.         }
  176.         catch (Exception e)
  177.         {
  178.             e.printStackTrace();
  179.         }
  180.         return image;
  181.     }
  182.     /**
  183.      * 生成二维码bufferedImage图片
  184.      * @param content  编码内容
  185.      * @param barcodeFormat 编码类型
  186.      * @param width 图片宽度
  187.      * @param height 图片高度
  188.      * @param hints 设置参数
  189.      * @return
  190.      */
  191.     public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)
  192.     {
  193.         MultiFormatWriter multiFormatWriter = null;
  194.         BitMatrix bm = null;
  195.         BufferedImage image = null;
  196.         try
  197.         {
  198.             multiFormatWriter = new MultiFormatWriter();
  199.             // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
  200.             bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);
  201.             int w = bm.getWidth();
  202.             int h = bm.getHeight();
  203.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  204.             // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
  205.             for (int x = 0; x < w; x++)
  206.             {
  207.                 for (int y = 0; y < h; y++)
  208.                 {
  209.                     image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
  210.                 }
  211.             }
  212.         }
  213.         catch (WriterException e)
  214.         {
  215.             e.printStackTrace();
  216.         }
  217.         return image;
  218.     }
  219.     /**
  220.      * 设置二维码的格式参数
  221.      * @return
  222.      */
  223.     public Map<EncodeHintType, Object> getDecodeHintType()
  224.     {
  225.         // 用于设置QR二维码参数
  226.         Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
  227.         // 设置QR二维码的纠错级别(H为最高级别)具体级别信息
  228.         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  229.         // 设置编码方式
  230.         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
  231.         hints.put(EncodeHintType.MARGIN, 0);
  232.         hints.put(EncodeHintType.MAX_SIZE, 350);
  233.         hints.put(EncodeHintType.MIN_SIZE, 100);
  234.         return hints;
  235.     }
  236. }
  237.     class LogoConfig
  238.     {
  239.         // logo默认边框颜色
  240.         public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
  241.         // logo默认边框宽度
  242.         public static final int DEFAULT_BORDER = 2;
  243.         // logo大小默认为照片的1/5
  244.         public static final int DEFAULT_LOGOPART = 5;
  245.         private final int border = DEFAULT_BORDER;
  246.         private final Color borderColor;
  247.         private final int logoPart;
  248.         /**
  249.          * Creates a default config with on color {@link #BLACK} and off color
  250.          * {@link #WHITE}, generating normal black-on-white barcodes.
  251.          */
  252.         public LogoConfig()
  253.         {
  254.             this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
  255.         }
  256.         public LogoConfig(Color borderColor, int logoPart)
  257.         {
  258.             this.borderColor = borderColor;
  259.             this.logoPart = logoPart;
  260.         }
  261.         public Color getBorderColor()
  262.         {
  263.             return borderColor;
  264.         }
  265.         public int getBorder()
  266.         {
  267.             return border;
  268.         }
  269.         public int getLogoPart()
  270.         {
  271.             return logoPart;
  272.         }
  273.     }

上述代码依赖于com.google.zxing这个插件,下载地址:http://maven.outofmemory.cn/com.google.zxing/core/3.1.0/

  1. <dependency>
  2.     <groupId>com.google.zxing</groupId>
  3.     <artifactId>core</artifactId>
  4.     <version>3.1.0</version>
  5. </dependency>

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!