最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java生成二维码可添加logo和文字功能
时间:2022-06-29 01:42:31 编辑:袖梨 来源:一聚教程网
代码如下 | 复制代码 |
packagecom.luo.wctweb.util; importjava.awt.Color; importjava.awt.Font; importjava.awt.Graphics2D; importjava.awt.image.BufferedImage; importjava.io.ByteArrayOutputStream; importjava.io.File; importjava.util.Date; importjava.util.HashMap; importjava.util.Map; importjavax.imageio.ImageIO; importjavax.servlet.http.HttpServletRequest; importcom.google.zxing.BarcodeFormat; importcom.google.zxing.EncodeHintType; importcom.google.zxing.MultiFormatWriter; importcom.google.zxing.WriterException; importcom.google.zxing.common.BitMatrix; importcom.google.zxing.qrcode.decoder.ErrorCorrectionLevel; importcom.lz.lsf.util.Base64; /** * @Description: (二维码) * @author:luoguohui * @date:2015-10-29 下午05:27:13 */ publicclassZXingCode { privatestaticfinalintQRCOLOR =0xFF000000;//默认是黑色 privatestaticfinalintBGWHITE =0xFFFFFFFF;//背景颜色 publicstaticvoidmain(String[] args)throwsWriterException { try { getLogoQRCode("https://www.baidu.com/",null,"跳转到百度的二维码"); } catch(Exception e) { e.printStackTrace(); } } /** * 生成带logo的二维码图片 * * @param qrPic * @param logoPic */ publicstaticString getLogoQRCode(String qrUrl,HttpServletRequest request,String productName) { // String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png"; //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好 String filePath ="C:/Users/luoguohui/Desktop/78310a55b319ebc4fa3aef658126cffc1f17168f.jpg";//TODO String content = qrUrl; try { ZXingCode zp =newZXingCode(); BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE,400,400, zp.getDecodeHintType()); returnzp.addLogo_QRCode(bim,newFile(filePath),newLogoConfig(), productName); } catch(Exception e) { e.printStackTrace(); } returnnull; } /** * 给二维码图片添加Logo * * @param qrPic * @param logoPic */ publicString addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName) { try { /** * 读取二维码图片,并构建绘图对象 */ BufferedImage image = bim; Graphics2D g = image.createGraphics(); /** * 读取Logo图片 */ BufferedImage logo = ImageIO.read(logoPic); /** * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码 */ intwidthLogo = 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放在中心 */ intx = (image.getWidth() - widthLogo) /2; inty = (image.getHeight() - heightLogo) /2; /** * logo放在右下角 * int x = (image.getWidth() - widthLogo); * int y = (image.getHeight() - heightLogo); */ //开始绘制图片 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(); //把商品名称添加上去,商品名称不要太长哦,这里最多支持两行。太长就会自动截取啦 if(productName !=null&& !productName.equals("")) { //新的图片,把带logo的二维码下面加上文字 BufferedImage outImage =newBufferedImage(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(newFont("宋体",Font.BOLD,30));//字体、字型、字号 intstrWidth = outg.getFontMetrics().stringWidth(productName); if(strWidth >399) { // //长度过长就截取前面部分 // outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字 //长度过长就换行 String productName1 = productName.substring(0, productName.length()/2); String productName2 = productName.substring(productName.length()/2, productName.length()); intstrWidth1 = outg.getFontMetrics().stringWidth(productName1); intstrWidth2 = outg.getFontMetrics().stringWidth(productName2); outg.drawString(productName1,200- strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2+12); BufferedImage outImage2 =newBufferedImage(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(newFont("宋体",Font.BOLD,30));//字体、字型、字号 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 =newByteArrayOutputStream(); baos.flush(); ImageIO.write(image,"png", baos); //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉 //可以看到这个方法最终返回的是这个二维码的imageBase64字符串 //前端用 其中${imageBase64QRCode}对应二维码的imageBase64字符串 ImageIO.write(image,"png",newFile("C:/Users/luoguohui/Desktop/TDC-"+newDate().getTime() +"test.png"));//TODO String imageBase64QRCode = Base64.byteArrayToBase64(baos.toByteArray()); baos.close(); returnimageBase64QRCode; } catch(Exception e) { e.printStackTrace(); } returnnull; } /** * 构建初始化二维码 * * @param bm * @return */ publicBufferedImage fileToBufferedImage(BitMatrix bm) { BufferedImage image =null; try { intw = bm.getWidth(), h = bm.getHeight(); image =newBufferedImage(w, h, BufferedImage.TYPE_INT_RGB); for(intx =0; x < w; x++) { for(inty =0; y < h; y++) { image.setRGB(x, y, bm.get(x, y) ?0xFF000000:0xFFCCDDEE); } } } catch(Exception e) { e.printStackTrace(); } returnimage; } /** * 生成二维码bufferedImage图片 * * @param content * 编码内容 * @param barcodeFormat * 编码类型 * @param width * 图片宽度 * @param height * 图片高度 * @param hints * 设置参数 * @return */ publicBufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat,intwidth,intheight, Map { MultiFormatWriter multiFormatWriter =null; BitMatrix bm =null; BufferedImage image =null; try { multiFormatWriter =newMultiFormatWriter(); // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数 bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints); intw = bm.getWidth(); inth = bm.getHeight(); image =newBufferedImage(w, h, BufferedImage.TYPE_INT_RGB); // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色 for(intx =0; x < w; x++) { for(inty =0; y < h; y++) { image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE); } } } catch(WriterException e) { e.printStackTrace(); } returnimage; } /** * 设置二维码的格式参数 * * @return */ publicMap { // 用于设置QR二维码参数 Map // 设置QR二维码的纠错级别(H为最高级别)具体级别信息 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置编码方式 hints.put(EncodeHintType.CHARACTER_SET,"utf-8"); hints.put(EncodeHintType.MARGIN,0); hints.put(EncodeHintType.MAX_SIZE,350); hints.put(EncodeHintType.MIN_SIZE,100); returnhints; } } classLogoConfig { // logo默认边框颜色 publicstaticfinalColor DEFAULT_BORDERCOLOR = Color.WHITE; // logo默认边框宽度 publicstaticfinalintDEFAULT_BORDER =2; // logo大小默认为照片的1/5 publicstaticfinalintDEFAULT_LOGOPART =5; privatefinalintborder = DEFAULT_BORDER; privatefinalColor borderColor; privatefinalintlogoPart; /** * Creates a default config with on color {@link #BLACK} and off color * {@link #WHITE}, generating normal black-on-white barcodes. */ publicLogoConfig() { this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART); } publicLogoConfig(Color borderColor,intlogoPart) { this.borderColor = borderColor; this.logoPart = logoPart; } publicColor getBorderColor() { returnborderColor; } publicintgetBorder() { returnborder; } publicintgetLogoPart() { returnlogoPart; } } |
相关文章
- 时空中的绘旅人天宇之间怎么玩 绘旅人天宇之间活动玩法介绍 12-25
- QQ2024年度报告怎么看 2024qq年度报告玩法介绍 12-25
- 归龙潮珠砂什么时候up 归龙潮红缘绮梦卡池介绍 12-25
- 王者荣耀S38赛季有什么更新 12-25
- 王者荣耀S38赛季有什么更新 王者荣耀S38赛季更新内容介绍 12-25
- 世界之外12.25有什么更新 世界之外12月25日更新内容介绍 12-25