欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java生成带logo和文字的二维码图片并以IO流返回给前端展示

程序员文章站 2022-07-14 17:35:58
...

废话不多说,直接贴代码

pom文件

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

请求接口



@RestController
//@RequestMapping("QrCode")
public class QrCodeController extends BaseController {

/**
     * @description: 获取二维码的方法,通过IO流返回,不再写入磁盘通过路径展示
     * @param shop_id
	 * @param shop_name
	 * @param response
     * @return void
     * @author: Ycc
     * @date: 2020/8/12
     * */

    @GetMapping("/getShopCode")
    public void getCode(String shop_id, String shop_name, HttpServletResponse response) throws IOException {

        //设置输出文件格式
        response.setContentType("image/png");
        
        // 存放在二维码中的内容
        String text = EncryptUtil.encrypt(shop_id) + "_hfyy";

        //获取二维码logo路径
        String logoPath = "F:/head/test.jpg";

        //二维码背景图路径
        String bgPath = "F:/head/2.png";

        //生成二维码
        BufferedImage qrCodeImage = QRcodeUtils.generateQrCode(text, logoPath);
        BufferedImage picture = QRcodeUtils.createPictureNew(qrCodeImage, bgPath, shop_name);

        //获取绘制好的图片的InputStream对象
        InputStream in = 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();
    }

    //从图片文件或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;
    }
}

二维码生成工具类

package cn.hangfeng.shop.common.utils;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * @description: 带文字的二维码
 * @author: Ycc
 * @since: 2020/7/13
 **/
public class QRcodeUtils {

    public static BufferedImage generateQrCode(String content, String logoPath) {
        BufferedImage image = QrCodeUtil.generate(
                content, // 二维码内容
                QrConfig.create().setImg(logoPath)// 附带logo
                        .setWidth(490) // 二维码的宽
                        .setHeight(490) // 二维码的高
                        .setMargin(0)); // 边距
        return image;
    }

  

    //区别于旧的方法
    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;
    }

}

打开浏览器访问接口测试
java生成带logo和文字的二维码图片并以IO流返回给前端展示

前端展示直接 src=“项目/接口”

参考(Ctrl c+v)文章地址
Java生成二维码并以IO流的形式返回给前端
java后台以IO流的形式将文件返回给前台进行展示

从图片文件或BufferedImage中得到InputStream

相关标签: IO流 java