精华内容
下载资源
问答
  • 直接输出到浏览器 不生成文件 可设置logo和文字 1.引入pom.xml <!-- 二维码 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <...

    直接输出到浏览器 不生成文件 可设置logo和文字

    1.引入pom.xml

        <!-- 二维码 -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>${zxing.core.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>${zxing.core.version}</version>
        </dependency>
    

    2.添加公共util.java

       //生成二维码 设置logo
        public static BufferedImage generateQrCode(String content, String logoPath) {
            BufferedImage image = QrCodeUtil.generate(
                    content, 													// 二维码内容
                    QrConfig.create().setImg(logoPath)		// 附带logo
                            .setWidth(500) 								// 二维码的宽
                            .setHeight(500) 								// 二维码的高
                            .setMargin(0)); 								// 边距
            return image;
        }
    
        //从图片文件或BufferedImage中得到InputStream
        public static InputStream getImageStream(BufferedImage bi) {
            InputStream is = null;
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            ImageOutputStream imOut;
            try {
                imOut = ImageIO.createImageOutputStream(bs);
                ImageIO.write(bi, "png", imOut);
                is = new ByteArrayInputStream(bs.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return is;
        }
    
        //创建新图片
        public static BufferedImage createPictureNew(BufferedImage image, String bgPath, String text) {
            try {
                // 首先先画背景图片
                BufferedImage backgroundImage = ImageIO.read(new File(bgPath));
                // 背景图片的宽度
                int bgWidth = backgroundImage.getWidth();
                // 二维码的宽度
                int qrWidth = image.getWidth();
                // 二维码距离背景图片横坐标(X)的距离,居中显示
                int distanceX = (bgWidth - qrWidth) / 2;
                // 二维码距离背景图片纵坐标(Y)的距离
                int distanceY = distanceX;
                // 基于图片backgroundImage对象打开绘图
                Graphics2D rng = backgroundImage.createGraphics();
                rng.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
                rng.drawImage(image, distanceX, distanceY, null);
    
                //设置字体
                Font font = new Font("宋体", Font.PLAIN, 30);
                rng.setFont(font);
                rng.setColor(Color.black);
                // 获取当前文字的对象
                FontMetrics metrics = rng.getFontMetrics(font);
    
                // 文字在图片中的坐标 这里设置在中间
                int startX = (bgWidth - metrics.stringWidth(text)) / 2; //当前文字对象到横坐标(X)的距离
                int startY = backgroundImage.getHeight()-10; //当前文字对象到纵坐标(Y)的距离
                rng.drawString(text, startX, startY);
                // 处理绘图
                rng.dispose();
                image = backgroundImage;
                image.flush();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 将绘制好的图片返回
            return image;
        }
    

    3.添加调用方法

        try {
            //设置输出文件格式
            response.setContentType("image/png");
            // 存放在二维码中的内容
    
            String text = stuNo;
            //获取二维码logo路径
            String logoPath = imgUrl + "logo.png";
            //二维码背景图路径 图片最好比较大一点
            String bgPath =  imgUrl + "logo_bg.png";
    
            //生成二维码
            BufferedImage qrCodeImage = QRcodeUtils.generateQrCode(text, logoPath);
            BufferedImage picture = QRcodeUtils.createPictureNew(qrCodeImage, bgPath, "设置文字");
    
            //获取绘制好的图片的InputStream对象
            InputStream in = QRcodeUtils.getImageStream(picture);
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            //创建存放文件内容的数组
            byte[] buff =new byte[1024];
            //所读取的内容使用n来接收
            int n;
            //当没有读取完时,继续读取,循环
            while((n=in.read(buff))!=-1){
                //将字节数组的数据全部写入到输出流中
                outputStream.write(buff,0,n);
            }
            //强制将缓存区的数据进行输出
            outputStream.flush();
            //关流
            outputStream.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    1. 部署到linux服务器 Graphics2D 中文乱码 乱码问题 请参考 https://blog.csdn.net/sinat_34797000/article/details/101107322
    展开全文
  • 使用zxing和hutool包来生成二维码,使用BufferedImage和Graphics2D来绘制图片 <dependencies> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</...

    使用zxing和hutool包来生成二维码,使用BufferedImage和Graphics2D来绘制图片

        <dependencies>
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.4.1</version>
            </dependency>
    
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.5.6</version>
            </dependency>
        </dependencies>

    主要代码

    package com.tgpms.web.tongfei.utils;
    
    import cn.hutool.core.util.StrUtil;
    import cn.hutool.extra.qrcode.QrCodeUtil;
    import cn.hutool.extra.qrcode.QrConfig;
    import sun.misc.BASE64Encoder;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    
    /**
     * @Author: jiangli
     * @Date: 2021/1/6 16:37
     * 合成二维码工具类
     */
    public class QrCoder {
    
        /**
         * 图片的宽度
         */
        private static final int IMAGE_WIDTH = 350;
        /**
         * 图片的高度(需按实际内容高度进行调整)
         */
        private static final int IMAGE_HEIGHT = 350;
        /**
         * 二维码的宽度
         */
        private static final int QR_CODE_WIDTH = 150;
        /**
         * 二维码的宽度
         */
        private static final int QR_CODE_HEIGHT = 150;
    
        private static final String FORMAT_NAME = "JPG";
    
        /**
         * @param imgLogo logo图片
         * @param title   头部标题
         * @param content 内容
         * @param footer  底部文字
         */
        public static BufferedImage createQrCode(String imgLogo, String title, String content, String footer) {
            // 头部文字区域高度
            int titleHeight = 50;
    
            // 创建主模板图片
            BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D main = image.createGraphics();
            // 设置图片的背景色
            main.setColor(Color.white); //白色
            main.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
    
            // 动态高度
            int height = 0;
    
            //***********************页面头部 文字****************
            Graphics2D titleRight = image.createGraphics();
            // 设置字体颜色 black黑 white白
            titleRight.setColor(Color.black);
            // 设置字体
            Font titleFont = new Font("宋体", Font.BOLD, 25);
            titleRight.setFont(titleFont);
            titleRight.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            // 居中 x开始的位置:(图片宽度-字体大小*字的个数)/2
            int x = (IMAGE_WIDTH - (titleFont.getSize() * title.length())) / 2;
            titleRight.drawString(title, x, (titleHeight) / 2 + 10);
            height += titleHeight;
    
            //**********************中间文字部分*********
            Graphics2D centerWord = image.createGraphics();
            // 设置字体颜色,先设置颜色,再填充内容
            centerWord.setColor(Color.black);
            // 设置字体
            Font wordFont = new Font("宋体", Font.PLAIN, 15);
            centerWord.setFont(wordFont);
            centerWord.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            String[] info = content.split("-");
            for (String s : info) {
                // x开始的位置:(图片宽度-字体大小*字的个数)/2
                int strWidth = centerWord.getFontMetrics().stringWidth(s);
                // 总长度减去文字长度的一半  (居中显示)
                int startX = (IMAGE_WIDTH - strWidth) / 2;
                height += 20;
                centerWord.drawString(s, startX, height);
            }
    
            //***************插入二维码图片***********************************************
            Graphics codePic = image.getGraphics();
            BufferedImage codeImg;
            QrConfig config = new QrConfig();
            config.setWidth(QR_CODE_WIDTH);
            config.setHeight(QR_CODE_HEIGHT);
            if (StrUtil.isNotBlank(imgLogo)) {
                config.setImg(imgLogo);
            }
            codeImg = QrCodeUtil.generate(content, config);
            // 绘制二维码
            codePic.drawImage(codeImg, (IMAGE_WIDTH - QR_CODE_WIDTH) / 2, height, QR_CODE_WIDTH, QR_CODE_HEIGHT, null);
            codePic.dispose();
    
            //**********************底部公司名字*********
            Graphics2D typeLeft = image.createGraphics();
            // 设置字体颜色
            typeLeft.setColor(Color.black);
            // 设置字体
            Font footerFont = new Font("宋体", Font.PLAIN, 10);
            typeLeft.setFont(footerFont);
            typeLeft.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            // x开始的位置:(图片宽度-字体大小*字的个数)/2
            int startX = (IMAGE_WIDTH - (footerFont.getSize() * footer.length())) / 2;
            height += QR_CODE_HEIGHT;
            typeLeft.drawString(footer, startX, height);
    
            //***************插入标志图片***********************************************
    //        Graphics signPic = image.getGraphics();
    //        BufferedImage signImg = null;
    //        try {
    //            signImg = ImageIO.read(new java.io.File(imgSign));
    //        } catch (Exception e) {
    //        }
    //
    //        if (signImg != null) {
    //            signPic.drawImage(signImg, 0, 130, QR_CODE_WIDTH, QR_CODE_HEIGHT, null);
    //            signPic.dispose();
    //        }
            // 返回image方便后续处理是生成图片还是生成base64字符串
            return image;
        }
    
        // 生成图片文件
        public static void createImage(BufferedImage image, String fileLocation) {
            if (image != null) {
                try {
                    ImageIO.write(image, "png", new File(fileLocation));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 获取图片base64数据
        public static String base64ImageString(BufferedImage image) throws IOException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();//io流
            ImageIO.write(image, FORMAT_NAME, bos);//写入流中
            byte[] bytes = bos.toByteArray();//转换成字节
            BASE64Encoder encoder = new BASE64Encoder();
            String jpgBase64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
            jpgBase64 = jpgBase64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
            return "data:image/jpg;base64," + jpgBase64;
        }
    
        public static void main(String[] args) {
            String content = "汇丰管业-HDPE节流式缠绕增强管-DN300-20210101-A001-0821001-080901000001";
            BufferedImage bufferedImage = createQrCode(null, "物资模块", content, "三峡科技有限公司");
            createImage(bufferedImage, "D:/test.png");
        }
    
    }

    效果图

    补充:如果要content的文字从左到右从上到下显示, 可以参考下面的方法, 主要是计算文字宽度和高度进行换行

    package com.tgpms.utils;
    
    import cn.hutool.core.collection.CollectionUtil;
    import cn.hutool.core.util.StrUtil;
    import cn.hutool.extra.qrcode.QrCodeUtil;
    import cn.hutool.extra.qrcode.QrConfig;
    import org.apache.commons.codec.binary.Base64;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * @author jiangli
     * @since 2021/1/6 16:37
     * 合成二维码工具类
     */
    public class QrCoder {
    
        // 用来调整水印的间距
        private static final int space = 2;
    
        /**
         * 图片的宽度
         */
        private static final int IMAGE_WIDTH = 150;
        /**
         * 图片的高度(需按实际内容高度进行调整)
         */
        private static final int IMAGE_HEIGHT = 300;
        /**
         * 二维码的宽度
         */
        private static final int QR_CODE_WIDTH = 150;
        /**
         * 二维码的高度
         */
        private static final int QR_CODE_HEIGHT = 150;
    
        private static final String FORMAT_NAME = "JPG";
    
        /**
         * @param imgLogo logo图片
         * @param title   头部标题
         * @param content 内容
         * @param footer  底部文字
         */
        public static BufferedImage createQrCode(String imgLogo, String title, String content, String footer) {
            // 头部文字区域高度
            int titleHeight = 50;
    
            // 创建主模板图片
            BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D main = image.createGraphics();
            // 设置图片的背景色
            main.setColor(Color.white); //白色
            main.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
    
            // 动态高度
            int height = 0;
    
            //***********************页面头部 文字****************
            Graphics2D titleRight = image.createGraphics();
            // 设置字体颜色 black黑 white白
            titleRight.setColor(Color.black);
            // 设置字体
            Font titleFont = new Font("宋体", Font.BOLD, 18);
            titleRight.setFont(titleFont);
            titleRight.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            // 居中 x开始的位置:(图片宽度-字体大小*字的个数)/2
            int x = (IMAGE_WIDTH - (titleFont.getSize() * title.length())) / 2;
            titleRight.drawString(title, x, (titleHeight) / 2 + 10);
            height += titleHeight;
    
            //**********************中间文字部分*********
            Graphics2D centerWord = image.createGraphics();
            // 设置字体颜色,先设置颜色,再填充内容
            centerWord.setColor(Color.black);
            // 设置字体
            Font wordFont = new Font("宋体", Font.PLAIN, 14);
            centerWord.setFont(wordFont);
            centerWord.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
    
            String words = content.substring(0, content.lastIndexOf("-"));
            List<String> waterMarkContents = Collections.singletonList(words);
            java.util.List<String> waterMarkContentList = new ArrayList<>();
            // 获取字符高度
            int strHeight = getStringHeight(centerWord);
            // 将换行后的文字放入新的集合
            for (String markContent : waterMarkContents) {
                // 单字符长度
                int tempCharLen = 0;
                // 单行字符总长度临时计算
                int tempLineLen = 0;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < markContent.length(); i++) {
                    char tempChar = markContent.charAt(i);
                    tempCharLen = getCharLen(tempChar, centerWord);
                    tempLineLen += tempCharLen;
                    // 文字长度大于图片宽度-2*间距-字体大小
                    if (tempLineLen > IMAGE_WIDTH - space * 2 - tempCharLen) {
                        // 长度已经满一行
                        waterMarkContentList.add(sb.toString());
                        // 清空内容,重新追加
                        sb.delete(0, sb.length());
                        tempLineLen = 0;
                    }
                    // 追加字符
                    sb.append(tempChar);
                }
                waterMarkContentList.add(sb.toString());
            }
            // 绘制内容文字
            if (CollectionUtil.isNotEmpty(waterMarkContentList)) {
                for (int i = 0; i < waterMarkContentList.size(); i++) {
                    String s = waterMarkContentList.get(i);
                    if (i > 0) {
                        //第一行不需要增加字符高度,以后的每一行在换行的时候都需要增加字符高度
                        height += strHeight;
                    }
                    centerWord.drawString(s, space, height);
                }
            }
    
            //***************插入二维码图片***********************************************
            Graphics codePic = image.getGraphics();
            BufferedImage codeImg;
            QrConfig config = new QrConfig();
            config.setMargin(0);
            config.setWidth(QR_CODE_WIDTH);
            config.setHeight(QR_CODE_HEIGHT);
            if (StrUtil.isNotBlank(imgLogo)) {
                config.setImg(imgLogo);
            }
            codeImg = QrCodeUtil.generate(content, config);
            // 绘制二维码
            codePic.drawImage(codeImg, (IMAGE_WIDTH - QR_CODE_WIDTH) / 2, height, QR_CODE_WIDTH, QR_CODE_HEIGHT, null);
            codePic.dispose();
    
            //**********************底部公司名字*********
            if (StrUtil.isNotBlank(footer)) {
                Graphics2D typeLeft = image.createGraphics();
                // 设置字体颜色
                typeLeft.setColor(Color.black);
                // 设置字体
                Font footerFont = new Font("宋体", Font.PLAIN, 10);
                typeLeft.setFont(footerFont);
                typeLeft.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
                // x开始的位置:(图片宽度-字体大小*字的个数)/2
                int startX = (IMAGE_WIDTH - (footerFont.getSize() * footer.length())) / 2;
                // 获取字符高度
                int footerStrHeight = getStringHeight(typeLeft);
                height += QR_CODE_HEIGHT + footerStrHeight;
                typeLeft.drawString(footer, startX, height);
            }
    
            //***************插入标志图片***********************************************
    //        Graphics signPic = image.getGraphics();
    //        BufferedImage signImg = null;
    //        try {
    //            signImg = ImageIO.read(new java.io.File(imgSign));
    //        } catch (Exception e) {
    //        }
    //
    //        if (signImg != null) {
    //            signPic.drawImage(signImg, 0, 130, QR_CODE_WIDTH, QR_CODE_HEIGHT, null);
    //            signPic.dispose();
    //        }
            // 返回image方便后续处理是生成图片还是生成base64字符串
            return image;
        }
    
        // 获取图片base64数据
        public static String base64ImageString(BufferedImage image) throws IOException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();//io流
            ImageIO.write(image, FORMAT_NAME, bos);//写入流中
            byte[] bytes = bos.toByteArray();//转换成字节
            String jpgBase64 = new String(Base64.encodeBase64(bytes)).trim();//转换成base64串
            jpgBase64 = jpgBase64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
            return "data:image/jpg;base64," + jpgBase64;
        }
    
        // 字符串总宽度
        private static int getStringLength(Graphics g, String str) {
            char[] chars = str.toCharArray();
            return g.getFontMetrics().charsWidth(chars, 0, str.length());
        }
    
        // 字符高度
        private static int getStringHeight(Graphics g) {
            return g.getFontMetrics().getHeight();
        }
    
        // 每一行字符的个数
        private static int getRowStrNum(int strNum, int rowWidth, int strWidth) {
            return (rowWidth * strNum) / strWidth;
        }
    
        // 字符行数
        private static int getRows(int strWidth, int rowWidth) {
            int rows;
            if (strWidth % rowWidth > 0) {
                rows = strWidth / rowWidth + 1;
            } else {
                rows = strWidth / rowWidth;
            }
            return rows;
        }
    
        public static int getCharLen(char c, Graphics2D g) {
            return g.getFontMetrics(g.getFont()).charWidth(c);
        }
    
        /**
         * 获取水印文字总长度
         *
         * @param waterMarkContent 水印的文字
         * @param g                绘图方法
         * @return 水印文字总长度
         */
        public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
            return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
        }
    
    }
    
            List<BufferedImage> images = new ArrayList<>();
            for (MaterialDetail detail : list) {
                StringJoiner sj = new StringJoiner("-");
                // 供货厂商-物资名称-规格-日期(yyyyMMdd)-流水号 -批号-物资编码
                String content = sj.add(detail.getSupplierAr()).add(detail.getName()).add(detail.getModel())
                        .add(detail.getDeliveryDate()).add(detail.getSort()).add(detail.getBatchNo()).add(detail.getMaterialNo()).toString();
                BufferedImage image = QrCoder.createQrCode(null, cwp, content, "三峡科技有限公司");
                images.add(image);
            }
            ImageToPdfUtil.downloadPdf(images, response);

    展开全文
  • java 生成二维码(QRCode)图片 ,包括logo,底部文字,压缩图片
  • 现在随着发展的需求的扩展,二维码的使用对于开发人员来说是一门必要的技能。下面我简单写了一个demo,二维码的生成工具。java生成二维码后返回前端使用img标签接收。

    目录

    1.java生成二维码工具类

    2.web测试

    3.前端处理

    4.测试结果


    • 背景

    本demo主要针对jdk1.6版本的,但是高版本的同样可以用,如果觉得不舒服可以自行添加高版本的依赖包。

    • 准备工具

    1. 依赖包
       
        <!--谷歌的jar包 主要的依赖包 -->
    		<dependency>
    		    <groupId>com.google.zxing</groupId>
    		    <artifactId>core</artifactId>
    		    <version>2.2</version>
    		</dependency>
    		<dependency>
    			<groupId>com.google.zxing</groupId>
    			<artifactId>javase</artifactId>
    			<version>2.2</version>
    		</dependency>
    
    
    
    <build>
    		<finalName>${project.artifactId}</finalName>
    		<plugins>
    			<!-- 资源文件拷贝插件 -->
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-resources-plugin</artifactId>
    				<version>2.7</version>
    				<configuration>
    					<encoding>UTF-8</encoding>
    				</configuration>
    			</plugin>
    			<!-- java编译插件;解决每次更新版本变化为1.5的问题 -->
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.2</version>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    					<encoding>UTF-8</encoding>
    				</configuration>
    			</plugin>
    		</plugins>
    		<pluginManagement>
    			<plugins>
    				<!-- 配置Tomcat插件 -->
    				<plugin>
    					<groupId>org.apache.tomcat.maven</groupId>
    					<artifactId>tomcat7-maven-plugin</artifactId>
    					<version>2.2</version>
    				</plugin>
    			</plugins>
    		</pluginManagement>
    	</build>

    1.java生成二维码工具类

    工具类的方法主要是用于二维码底部显示对应的文字,至于在二维码添加logo的没有做,因为本人的需求没有涉及到。但是实现的思路就是引入一个logo图片通过设置其大小小于二维码的尺寸,然后通过java的画图方式将logo画在二维码上面

    package com.tecrun.utils.qrcode;
    
    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.HashMap;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.commons.net.util.Base64;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.Result;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.client.j2se.MatrixToImageConfig;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    
    /**
     * 二维码工具类
     * @author tchzt
     *
     */
    public class QRCodeUtil {
    	//二维码的宽高
    	private static final int WIDTH=200;
    	private static final int HEIGHT=200;
    	// 加文字二维码高
    	private static final int WORDHEIGHT = 250; 
    	
    	/**
    	 *  生成二维码图片
    	 * @param content 二维码的内容
    	 * @return
    	 */
    	public static BufferedImage createQRCode(String content) {
    		
    		Map<EncodeHintType, Object> hints= new HashMap<EncodeHintType, Object>();
    		//容错级别L>M>Q>H(级别越高扫描时间越长)
    		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
    		//字符编码
    		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    		hints.put(EncodeHintType.MARGIN, 0);//白边的宽度,可取0~4
    		BufferedImage image=null;									
    		try {
    			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
    			//生成矩阵数据
    			BitMatrix bitMatrix=multiFormatWriter.encode(content, 
    					BarcodeFormat.QR_CODE,WIDTH,HEIGHT,hints);	
    			int w = bitMatrix.getWidth();
    			int h = bitMatrix.getHeight();
    			//生成二维码bufferedImage图片
    			image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    			// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
    			for (int x = 0; x < w; x++) {
    				for (int y = 0; y < h; y++) {
    					image.setRGB(x, y, bitMatrix.get(x, y) ? 
    							MatrixToImageConfig.BLACK : MatrixToImageConfig.WHITE);
    				}
    			}
    			
    											
    		} catch (Exception e) {
    			throw new RuntimeException("生成二维码失败:"+e.getMessage());
    	    }							
    		return image;
    		
    	}
    	
    	/**
    	 *  生成解析二维码
    	 * @param content 二维码的内容
    	 * @return
    	 */
    	public static Result parseQRCode(String filePath) {
    		//二维码编码相关的参数
    		Map<DecodeHintType, Object> hints= new HashMap<DecodeHintType, Object>();
    		//字符编码
    		hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
    
    		BufferedImage image=null;
    		try {
    			File file = new File(filePath);
    			image = ImageIO.read(file);
    			
    			if (image == null) {
    				System.out.println("the decode image may be not exit.");
    			}
    			LuminanceSource source = new BufferedImageLuminanceSource(image);
    			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    			//解析二维码
    			Result result = new MultiFormatReader().decode(bitmap, hints);
    			
    			return result;
    		} catch (Exception e) {
    			throw new RuntimeException("解析二维码失败:"+e.getMessage());
    	    }
    		
    	}
    	
    	/**
    	 *  删除生成的二维码周围的白边,根据审美决定是否删除
    	 * @param matrix BitMatrix对象
    	 * @return BitMatrix对象
    	 * */
    	private static BitMatrix deleteWhite(BitMatrix matrix) {
    	    int[] rec = matrix.getEnclosingRectangle();
    	    int resWidth = rec[2] + 1;
    	    int resHeight = rec[3] + 1;
    
    	    BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
    	    resMatrix.clear();
    	    for (int i = 0; i < resWidth; i++) {
    	        for (int j = 0; j < resHeight; j++) {
    	            if (matrix.get(i + rec[0], j + rec[1]))
    	                resMatrix.set(i, j);
    	        }
    	    }
    	    return resMatrix;
    	} 
    	
    	 /**
    	    * 二维码底部加上文字
    	    * @param image 传入二维码对象
    	    * @param words 显示的文字内容 
    	    * @return
    	    */
    	   private static BufferedImage insertWords(BufferedImage image,String words){
    		   BufferedImage outImage = null;
    			if (  StringUtils.isNotBlank(words)){
    				outImage= new BufferedImage(WIDTH, WORDHEIGHT, 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.PLAIN, 16)); // 字体、字型、字号
    				
    				int strWidth = outg.getFontMetrics().stringWidth(words);
    				
    				int singleFD=outg.getFontMetrics().stringWidth("2");
    				int grow=WIDTH/singleFD-1;
    				//长度过长就截取超出二维码宽度部分换行
    				if (strWidth > WIDTH) {
    					String serialnum1 = words.substring(0, grow);
    					String serialnum2 = words.substring(grow, words.length());
    					outg.drawString(serialnum1, 5, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 );
    					BufferedImage outImage2 = new BufferedImage(WIDTH, WORDHEIGHT, 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.PLAIN, 16)); 
    					//参数:显示的内容、起始位置x、起始的y
    					outg2.drawString(serialnum2,5, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 );
    					outg2.dispose();
    					outImage2.flush();
    					outImage = outImage2;
    				} else {
    					// 画文字
    					outg.drawString(words, (WIDTH - strWidth) / 2, 
    							image.getHeight() + (outImage.getHeight() - image.getHeight()) / 3 ); 
    				}
    				outg.dispose();
    				outImage.flush();
    				image.flush();
    			}
    		  
    	      return outImage;
    	}
    	   
    	   
    	/**
    	 * 生成二维码下方不带文字
    	 * @return
    	 */
    	public static String getQRCode(String srialnum,String savePath) {
    		BufferedImage image=createQRCode(srialnum);
    		try {
    			
    			//字节数组流包装输出对象流
    			ByteArrayOutputStream baos = new ByteArrayOutputStream();
    			ImageIO.write(image, "png", baos);//将图片写入到输出流
    			ImageIO.write(image, "png", new File(savePath));//直接写入某路径
    			return Base64.encodeBase64URLSafeString(baos.toByteArray());
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new RuntimeException("写出图片流失败");
    		}
    		
    	}
    	
    	/**
    	 * 生成的二维码下方带文字
    	 * @return
    	 */
    	public static String getQRCode(String srialnum,String words,String savePath) {
    		
    		BufferedImage image = insertWords(createQRCode(srialnum), words);
    		try {
    			
    			//字节数组流包装输出对象流
    			ByteArrayOutputStream baos = new ByteArrayOutputStream();
    			image.flush();
    			//将图片写入到输出流
    			ImageIO.write(image, "png", baos);
    			
    			ImageIO.write(image, "png", new File(savePath));//直接写入某路径
    			return Base64.encodeBase64URLSafeString(baos.toByteArray());
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new RuntimeException("写出图片流失败!!!");
    		}
    		
    	}
    	
    	public static void main(String[] args) {
    		String srialnum="123726387628736581235";
    		String words="987345972934723123123435234523452345";
    		String savePath="E:\\桌面\\image\\03.jpg";
    		getQRCode(srialnum,words,savePath);
    //		getQRCode(srialnum,savePath);
    		System.out.println("ok");
    		
    		//去掉固定长度字符串的空格问题
    		String string= "       uiiuhi kkjsnf jkjk  ";		
    		System.out.println(string.replace(" ", ""));
    	}
    }
    	
    

    2.web测试

    创建一个简单web项目,引入对应的jar包,将二维码工具类放入到工具类包下,写一个简单的controller类进行web测试。

    /**
    	 * 
    	* @Title: showQRCode 
    	* @Description: 测试二维码输出到前端显示
    	* @return String
    	* @author tchzt
    	 * @throws IOException 
    	* @date 2021年9月17日下午6:02:32
    	 */
    	@RequestMapping("/qrcode")
    	public void showQRCode(HttpServletResponse response) throws IOException {
    
    	    String words="254352397459dfasdgvxdvser3453452sfsdg454353wtwegd82374";
    	    
    	    String code = QRCodeUtil.getQRCode(words, words);
    	    //解析二维码的base64流
    	    byte[] base64 = Base64.decodeBase64(code);
    	    ByteArrayOutputStream baos= new ByteArrayOutputStream();
    	    baos.write(base64);
    	    //获取HttpServletResponse响应流,用于输出到前端
    	    ServletOutputStream outputStream = response.getOutputStream();
    	    baos.writeTo(outputStream);
    	    outputStream.close();
    	    baos.close();
    	   	
    	}

    3.前端处理

            使用img接收服务器响应的图片流,由于考虑到服务地址的变化,首先通过js获取到服务器的地址,这样不会因为服务变化而导致不能使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    
    </head>
    <body>
    
    <img id="qrcode" alt="#" src="">
    
    <script type="text/javascript">
       /* 获取服务地址  */
       var curWPath = window.document.location.href;
       var pathname = window.document.location.pathname;
       var index = curWPath.indexOf(pathname);
       var serverpath = curWPath.substring(0,index);
       /* 设置二维码的服务URL */
       var qrcodeobj = document.getElementById("qrcode");
       qrcodeobj.src = serverpath+"/qrcode";
       console.log("imgsrc="+qrcodeobj.src);
       alert(qrcodeobj.src);
       
    </script>
    </body>
    </html>

    4.测试结果

    展开全文
  • 主要介绍了Java生成二维码可添加logo和文字功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
  • Java生成二维码工具类,可生成二维码+logo+文字说明,封装好,可直接调用!主要是运用google的zxing插件!
  • java生成二维码Demo,执行mian方法生成二维码。text传递url生成网页二维码,传递非url生成文字二维码。非常方便。。。
  • Java生成二维码

    2017-02-14 14:08:37
    Java生成二维码,可添加图片logo和文字
  • --生成二维码--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-extra</artifactId> <version>5.4.3</version> </dependency> <...

    1pom.xml

    <!--生成二维码-->
    <dependency>
       <groupId>cn.hutool</groupId>
       <artifactId>hutool-extra</artifactId>
       <version>5.4.3</version>
    </dependency>
    <dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>core</artifactId>
       <version>3.3.3</version>
    </dependency>
    
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    2.工具类

    package com.example.QRcode.utils;
    
    import cn.hutool.extra.qrcode.QrCodeUtil;
    import cn.hutool.extra.qrcode.QrConfig;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    import org.springframework.core.io.DefaultResourceLoader;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.util.ResourceUtils;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @Description: 在图片上生成二维码并且在图片上添加文字response前端
     * @Auther: yjj
     * @Date: 2020/9/23 18:57
     */
    public class QRcodeImageFont {
    
        /***
         * 在一张背景图上添加二维码
         */
        public static void drawString(String content, HttpServletResponse response) throws Exception {
            BufferedImage image = addWater(content);
            Graphics2D gd = image.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            gd.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            // 5、设置水印文字颜色
            gd.setColor(Color.red);
            // 6、设置水印文字Font
            gd.setFont(new Font("宋体", Font.BOLD, 20));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            gd.drawString("测试文字", 90, 260);
            gd.dispose();
            // 输出图片
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(image, "png",outputStream );
            System.out.println("添加水印完成");
            outputStream.flush();
            outputStream.close();
        }
    
        /***
         * 在一张背景图上添加二维码
         */
        public static BufferedImage addWater(String content) throws Exception {
            // 读取原图片信息
            //得到文件
            File file = ResourceUtils.getFile("classpath:static/img/code.png");
            //文件转化为图片
            Image srcImg = ImageIO.read(file);
            //获取图片的宽
            int srcImgWidth = srcImg.getWidth(null);
            //获取图片的高
            int srcImgHeight = srcImg.getHeight(null);
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
            //使用工具类生成二维码
            Image image = createQrCode(content,200,200);
            //将小图片绘到大图片上,500,300 .表示你的小图片在大图片上的位置。
            g.drawImage(image, 70, 300, null);
            //设置颜色。
            g.setColor(Color.WHITE);
            g.dispose();
            return bufImg;
        }
    
        private static BufferedImage createQrCode(String content, int width, int height) throws IOException {
            QrConfig config = new QrConfig(width, height);
    
            Image image = ImageIO.read(resourceLoader("classpath:static/img/onlyLogo.png"));
            config.setImg(image);
            config.setErrorCorrection(ErrorCorrectionLevel.H);
            return QrCodeUtil.generate(
                    content,
                    config);
        }
    
        public static InputStream resourceLoader(String fileFullPath) throws IOException {
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            return resourceLoader.getResource(fileFullPath).getInputStream();
        }
    }

    3.底图和logo

     

    4.测试

    package com.example.QRcode.controller;
    
    import com.example.QRcode.utils.QRcodeImageFont;
    import com.example.QRcode.utils.QRcodeImageUtils;
    import com.example.QRcode.utils.QRcodeUtils;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @Description:
     * @Auther: yjj
     * @Date: 2020/9/23 18:58
     */
    @RestController
    @RequestMapping(value = "/test")
    public class TestController {
    
        @GetMapping("/createQrCode")
        public void createQrCode(@RequestParam("url") String url, HttpServletResponse response) throws Exception {
           
            //在图片上生成二维码,并在图片上添加文字描述
            QRcodeImageFont.drawString(url,response);
        }
    }

    5.展示

    展开全文
  • 生成指定文字内容的二维码 二维码中间嵌入LOGO 二维码做圆角和白色边框处理 新需求不断, 这不, 又来了个想生成带用户头像的需求. 蛮简单的… 在这里造完轮子分享给大家 因为公司后端主要是Kotlin写的. 请大家自行...
  • java 使用zxing生成二维码logo和文字说明)已经封装 使用起来很方便 下载下来直接调用传入参数就可以
  • java生成二维码

    2017-10-31 17:59:56
    java给以个图片再生成带图片的二维码,String是连接或者文字
  • JAVA生成二维码

    2020-08-27 16:47:25
    一步一步教你用java生成二维码 一步一步用 java 设计生成二维码 在物联网的时代,二维码是个很重要的东西了,现在无论什么东西都要搞个二维码标志,唯恐落伍,就差人没有用二维码识别了。也许有...
  • 二维码生成PDF文件保存二维码附加文字信息前言一、引入依赖二、创建实体类1.文字信息对象2.创建QRCodeUtil总结如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容...
  • 生成带logo的二维码图片,已测试
  • <!--生成二维码依赖 --> <groupId>commons-codec <artifactId>commons-codec <version>1.8 <groupId>com.google.zxing</groupId> <artifactId>javase</artif
  • 使用Java生成二维码

    2020-08-21 18:45:24
    如何使用Java生成二维码 文章目录如何使用Java生成二维码1、使用的技术架构2、准备工作2.1导入需要的maven依赖2.2创建两个工具类1 、BufferedImageLuminanceSource类,用于解析二维码2、QRCodeUtil类 ,用于生成...
  • Java 生成二维码

    2020-05-27 00:31:34
    Java 生成二维码。 文章目录Java 生成二维码。二维码。发展。一维码。二维码。优缺点。QR Code。生成方法。第三方 jar。eg. zxing 和 qrcodejar。JavaScript。eg. jquery.qrcode.js。ZXing Project。zxing 解析。...
  • java生成二维码(qrcodeutils.java)
  • java生成二维码.zip

    2019-06-03 11:48:24
    java 使用zxing生成二维码logo和文字说明)已经封装 使用起来很方便 下载下来直接调用传入参数就可以
  • // 生成带logo的二维码图片 public static void drawLogoQRCode(File logoFile, File codeFile, String qrUrl, String note) { try { MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); // 参数...
  • java生成二维码(图片下方附文字

    千次阅读 2019-07-22 15:53:18
    java生成二维码(图片下方附文字)QRCodeUtilEx.java 工作中需要生成二维码使用,通过参考以下博客: https://blog.csdn.net/qq_19707521/article/details/69568387 ...并经过自己的修改达到可用的程度。...
  • 通过java生成二维码首先下载谷歌提供的两个jar 链接:https://pan.baidu.com/s/1ZrNXHaUNnfuiADM4D4VOvQ 提取码:0hn5 然后自定义类 public class QrCodeUtil { //生成二维码图片输出流 private static ...
  • java 生成二维码,二维码中间可以夹杂logo图片,两张图片合并成一张或添加水印文字,添加jar包 <!-- google生成二维码 --> <groupId>com.google.zxing</groupId> <artifactId>core <version>3.1.0 ...
  • public class QRCodeUtils { /** * 生成二维码 * */ public static BufferedImage getImg(String content, int size) throws Exception { //其他参数,如字符集编码 Map hints = new HashMap(); hints.put...
  • java生成二维码,且中间图片(logo)的方法,且logo的具体位置可以自己设置,下载下来就能运行的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,901
精华内容 2,360
关键字:

java生成二维码带文字

java 订阅