欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java生成中間logo的二維碼的示例代碼

 更新時(shí)間:2020年07月28日 10:48:25   作者:看云  
這篇文章主要介紹了Java如何生成中間logo的二維碼,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

最近有負(fù)責(zé)微信開(kāi)發(fā),對(duì)于微信開(kāi)發(fā)的項(xiàng)目,肯定少不了二維碼啦,正好有個(gè)這樣的需求,這對(duì)不同的商品生成一個(gè)二維碼,掃碼即刻下單。博主就弄了一個(gè)二維碼生成的工具類。

弄出來(lái)之后,產(chǎn)品經(jīng)理又說(shuō)了,中間放上公司的logo是不是好一點(diǎn)?加上吧,

加上公司logo之后,產(chǎn)品經(jīng)理想了想,每個(gè)商品都有個(gè)二維碼,銷售人員有很多個(gè)商品二維碼,群發(fā)給用戶,在qq群上,微信群上,怎么知道哪個(gè)二維碼對(duì)應(yīng)哪個(gè)商品的呢?于是決定要加上商品名稱。最后商品二維碼就成了下面這個(gè)模樣了(當(dāng)然啦,這里面的logo并不是博主現(xiàn)職公司的)。

效果已經(jīng)出來(lái)啦,下面附上代碼啦

如果讀者不需要logo或者二維碼名稱的,讀懂代碼后進(jìn)行刪減即可。注釋多多,還是很容易看懂的。

package com.luo.wctweb.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.lz.lsf.util.Base64;

/** 
 * @Description: (二維碼)   
 * @author:luoguohui 
 * @date:2015-10-29 下午05:27:13   
 */
public class ZXingCode
{
  private static final int QRCOLOR = 0xFF000000;  //默認(rèn)是黑色
  private static final int BGWHITE = 0xFFFFFFFF;  //背景顏色

  public static void main(String[] args) throws WriterException 
  { 
    try 
    { 
      getLogoQRCode("https://www.baidu.com/", null, "跳轉(zhuǎn)到百度的二維碼");
    } 
    catch (Exception e) 
    { 
      e.printStackTrace(); 
    } 
  } 

  /**
   * 生成帶logo的二維碼圖片
   *
   * @param qrPic
   * @param logoPic
   */
  public static String getLogoQRCode(String qrUrl,HttpServletRequest request,String productName)
  {
//   String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";
    //filePath是二維碼logo的路徑,但是實(shí)際中我們是放在項(xiàng)目的某個(gè)路徑下面的,所以路徑用上面的,把下面的注釋就好
    String filePath = "C:/Users/luoguohui/Desktop/78310a55b319ebc4fa3aef658126cffc1f17168f.jpg"; //TODO 
    String content = qrUrl;
    try
    { 
      ZXingCode zp = new ZXingCode();
      BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400, 400, zp.getDecodeHintType());
      return zp.addLogo_QRCode(bim, new File(filePath), new LogoConfig(), productName);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 給二維碼圖片添加Logo
   *
   * @param qrPic
   * @param logoPic
   */
  public String addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName)
  {
    try
    {
      /**
       * 讀取二維碼圖片,并構(gòu)建繪圖對(duì)象
       */
      BufferedImage image = bim;
      Graphics2D g = image.createGraphics();

      /**
       * 讀取Logo圖片
       */
      BufferedImage logo = ImageIO.read(logoPic);
      /**
       * 設(shè)置logo的大小,本人設(shè)置為二維碼圖片的20%,因?yàn)檫^(guò)大會(huì)蓋掉二維碼
       */
      int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null), 
        heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);

      /**
       * logo放在中心
       */
       int x = (image.getWidth() - widthLogo) / 2;
       int y = (image.getHeight() - heightLogo) / 2;
       /**
       * logo放在右下角
       * int x = (image.getWidth() - widthLogo);
       * int y = (image.getHeight() - heightLogo);
       */

      //開(kāi)始繪制圖片
      g.drawImage(logo, x, y, widthLogo, heightLogo, null);
//      g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
//      g.setStroke(new BasicStroke(logoConfig.getBorder()));
//      g.setColor(logoConfig.getBorderColor());
//      g.drawRect(x, y, widthLogo, heightLogo);
      g.dispose();

      //把商品名稱添加上去,商品名稱不要太長(zhǎng)哦,這里最多支持兩行。太長(zhǎng)就會(huì)自動(dòng)截取啦
      if (productName != null && !productName.equals("")) {
        //新的圖片,把帶logo的二維碼下面加上文字
        BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D outg = outImage.createGraphics();
        //畫二維碼到新的面板
        outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
        //畫文字到新的面板
        outg.setColor(Color.BLACK); 
        outg.setFont(new Font("宋體",Font.BOLD,30)); //字體、字型、字號(hào) 
        int strWidth = outg.getFontMetrics().stringWidth(productName);
        if (strWidth > 399) {
//         //長(zhǎng)度過(guò)長(zhǎng)就截取前面部分
//         outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //畫文字
          //長(zhǎng)度過(guò)長(zhǎng)就換行
          String productName1 = productName.substring(0, productName.length()/2);
          String productName2 = productName.substring(productName.length()/2, productName.length());
          int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
          int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
          outg.drawString(productName1, 200 - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );
          BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
          Graphics2D outg2 = outImage2.createGraphics();
          outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
          outg2.setColor(Color.BLACK); 
          outg2.setFont(new Font("宋體",Font.BOLD,30)); //字體、字型、字號(hào) 
          outg2.drawString(productName2, 200 - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
          outg2.dispose(); 
          outImage2.flush();
          outImage = outImage2;
        }else {
          outg.drawString(productName, 200 - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //畫文字 
        }
        outg.dispose(); 
        outImage.flush();
        image = outImage;
      }
      logo.flush();
      image.flush();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      baos.flush();
      ImageIO.write(image, "png", baos);

      //二維碼生成的路徑,但是實(shí)際項(xiàng)目中,我們是把這生成的二維碼顯示到界面上的,因此下面的折行代碼可以注釋掉
      //可以看到這個(gè)方法最終返回的是這個(gè)二維碼的imageBase64字符串
      //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}對(duì)應(yīng)二維碼的imageBase64字符串
      ImageIO.write(image, "png", new File("C:/Users/luoguohui/Desktop/TDC-" + new Date().getTime() + "test.png")); //TODO 

      String imageBase64QRCode = Base64.byteArrayToBase64(baos.toByteArray());
      baos.close();
      return imageBase64QRCode;
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 構(gòu)建初始化二維碼
   *
   * @param bm
   * @return
   */
  public BufferedImage fileToBufferedImage(BitMatrix bm)
  {
    BufferedImage image = null;
    try
    {
      int w = bm.getWidth(), h = bm.getHeight();
      image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

      for (int x = 0; x < w; x++)
      {
        for (int y = 0; y < h; y++)
        {
          image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
        }
      }

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return image;
  }

  /**
   * 生成二維碼bufferedImage圖片
   *
   * @param content
   *      編碼內(nèi)容
   * @param barcodeFormat
   *      編碼類型
   * @param width
   *      圖片寬度
   * @param height
   *      圖片高度
   * @param hints
   *      設(shè)置參數(shù)
   * @return
   */
  public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)
  {
    MultiFormatWriter multiFormatWriter = null;
    BitMatrix bm = null;
    BufferedImage image = null;
    try
    {
      multiFormatWriter = new MultiFormatWriter();
      // 參數(shù)順序分別為:編碼內(nèi)容,編碼類型,生成圖片寬度,生成圖片高度,設(shè)置參數(shù)
      bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);
      int w = bm.getWidth();
      int h = bm.getHeight();
      image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

      // 開(kāi)始利用二維碼數(shù)據(jù)創(chuàng)建Bitmap圖片,分別設(shè)為黑(0xFFFFFFFF)白(0xFF000000)兩色
      for (int x = 0; x < w; x++)
      {
        for (int y = 0; y < h; y++)
        {
          image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
        }
      }
    }
    catch (WriterException e)
    {
      e.printStackTrace();
    }
    return image;
  }

  /**
   * 設(shè)置二維碼的格式參數(shù)
   *
   * @return
   */
  public Map<EncodeHintType, Object> getDecodeHintType()
  {
    // 用于設(shè)置QR二維碼參數(shù)
    Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
    // 設(shè)置QR二維碼的糾錯(cuò)級(jí)別(H為最高級(jí)別)具體級(jí)別信息
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    // 設(shè)置編碼方式
    hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    hints.put(EncodeHintType.MARGIN, 0);
    hints.put(EncodeHintType.MAX_SIZE, 350);
    hints.put(EncodeHintType.MIN_SIZE, 100);

    return hints;
  }
}

  class LogoConfig
  {
    // logo默認(rèn)邊框顏色
    public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
    // logo默認(rèn)邊框?qū)挾?
    public static final int DEFAULT_BORDER = 2;
    // logo大小默認(rèn)為照片的1/5
    public static final int DEFAULT_LOGOPART = 5;

    private final int border = DEFAULT_BORDER;
    private final Color borderColor;
    private final int logoPart;

    /**
     * Creates a default config with on color {@link #BLACK} and off color
     * {@link #WHITE}, generating normal black-on-white barcodes.
     */
    public LogoConfig()
    {
      this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
    }

    public LogoConfig(Color borderColor, int logoPart)
    {
      this.borderColor = borderColor;
      this.logoPart = logoPart;
    }

    public Color getBorderColor()
    {
      return borderColor;
    }

    public int getBorder()
    {
      return border;
    }

    public int getLogoPart()
    {
      return logoPart;
    }
  }

需要說(shuō)明的是以上代碼依賴了com.google.zxing這個(gè)插件,如果讀者跟博主一樣都是使用maven的話,添加下面依賴即可。
如果沒(méi)有用maven的話,直接在http://maven.outofmemory.cn/com.google.zxing/core/3.1.0/ 下載。

<dependency>
  <groupId>com.google.zxing</groupId>
  <artifactId>core</artifactId>
  <version>3.1.0</version>
</dependency>

以上就是Java生成中間logo的二維碼的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java生成中間logo的二維碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring中@Value使用詳解及SPEL表達(dá)式

    Spring中@Value使用詳解及SPEL表達(dá)式

    這篇文章主要介紹了Spring中@Value使用詳解及SPEL表達(dá)式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Spring Boot項(xiàng)目中如何對(duì)接口請(qǐng)求參數(shù)打印日志

    Spring Boot項(xiàng)目中如何對(duì)接口請(qǐng)求參數(shù)打印日志

    在SpringBoot項(xiàng)目中,打印接口請(qǐng)求參數(shù)有多種方法,如使用AOP、控制器建議、攔截器、@ModelAttribute、SpringBootActuator、日志框架的MDC、自定義過(guò)濾器和SpringWebflux,這些方法有助于API調(diào)試和監(jiān)控,但需注意隱私和敏感信息安全
    2024-10-10
  • 如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問(wèn)題

    如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問(wèn)題

    這篇文章主要介紹了如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java中class和Class的區(qū)別示例詳解

    Java中class和Class的區(qū)別示例詳解

    class 是java的關(guān)鍵字,在聲明java類時(shí)使用,Class是java JDK提供的一個(gè)類,完整路徑為java.lang.Class,下面這篇文章主要給大家介紹了關(guān)于Java中class和Class區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Java中notify是順序喚醒還是隨機(jī)喚醒的

    Java中notify是順序喚醒還是隨機(jī)喚醒的

    這篇文章主要介紹了Java中notify是順序喚醒還是隨機(jī)喚醒的,有很多人會(huì)認(rèn)為?notify?是隨機(jī)喚醒的,但它真的是隨機(jī)喚醒的嗎?帶著疑問(wèn)一起進(jìn)入文章了解具體的內(nèi)容吧
    2022-05-05
  • springboot中pom.xml文件注入test測(cè)試依賴時(shí)報(bào)錯(cuò)的解決

    springboot中pom.xml文件注入test測(cè)試依賴時(shí)報(bào)錯(cuò)的解決

    這篇文章主要介紹了springboot中pom.xml文件注入test測(cè)試依賴時(shí)報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 解決springboot整合druid遇到的坑

    解決springboot整合druid遇到的坑

    這篇文章主要介紹了解決springboot整合druid遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • IntelliJ IDEA中ajax開(kāi)發(fā)實(shí)現(xiàn)分頁(yè)查詢示例

    IntelliJ IDEA中ajax開(kāi)發(fā)實(shí)現(xiàn)分頁(yè)查詢示例

    這篇文章主要介紹了IntelliJ IDEA中ajax開(kāi)發(fā)實(shí)現(xiàn)分頁(yè)查詢,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 詳解HttpSecurity是如何組裝過(guò)濾器鏈的

    詳解HttpSecurity是如何組裝過(guò)濾器鏈的

    HttpSecurity 本質(zhì)上也是一個(gè) SecurityBuilder,我們平時(shí)在 HttpSecurity 配置的各種東西,本質(zhì)上其實(shí)就是一個(gè) xxxConfigure,這些 xxxConfigure 被 HttpSecurity 收集起來(lái),本文將給大家介紹HttpSecurity是如何組裝過(guò)濾器鏈的,需要的朋友可以參考下
    2024-06-06
  • Java對(duì)象的內(nèi)存布局全流程

    Java對(duì)象的內(nèi)存布局全流程

    這篇文章主要介紹了Java對(duì)象的內(nèi)存布局全流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05

最新評(píng)論