java实现图片和二维码的合成

实现结果

 

实现步骤

1.导入谷歌合成二维码和图片的jar包


<!-- 配置二维码生成的框架 -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.1.0</version>
</dependency>

2.实现二维码和图片的生成代码,响应前台图片显示参考转换base64格式显示否则乱码无法展示

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author 萧何
 * @Date 2020/8/16 17:47
 */
public class ImgUtil {
    /**
     * 定义二维码图片的宽度
     */
    private static final int WIDTH = 125;
    /**
     * 定义二维码图片的高度
     */
    private static final int HEIGHT = 125;

    /**
     * 定义LOGO图片的宽度
     */
    private static final int LOGO_WIDTH = 40;
    /**
     * 定义LOGO图片的高度
     */
    private static final int LOGO_HEIGHT = 40;


    /**
     * 生成二维码的方法
     */
    public static BufferedImage execute() throws Exception {
        /** 判断二维码中URL */
        String url =null;
        if (url == null || "".equals(url)) {
            url = "礼好啊奥里给!";
        }

        /** 定义Map集合封装二维码配置信息 */
        Map<EncodeHintType, Object> hints = new HashMap<>();
        /** 设置二维码图片的内容编码 */
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        /** 设置二维码图片的上、下、左、右间隙 */
        hints.put(EncodeHintType.MARGIN, 1);
        /** 设置二维码的纠错级别 */
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        /**
         * 创建二维码字节转换对象
         * 第一个参数:二维码图片中的内容
         * 第二个参数:二维码格式器
         * 第三个参数:生成二维码图片的宽度
         * 第四个参数:生成二维码图片的高度
         * 第五个参数:生成二维码需要配置信息
         *  */
        BitMatrix matrix = new MultiFormatWriter().encode(url,
                BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);

        /** 获取二维码图片真正的宽度  */
        int matrix_width = matrix.getWidth();
        /** 获取二维码图片真正的高度  */
        int matrix_height = matrix.getHeight();
        /** 定义一张空白的缓冲流图片 */
        BufferedImage image = new BufferedImage(matrix_width, matrix_height,
                BufferedImage.TYPE_INT_RGB);
        /** 把二维码字节转换对象 转化 到缓冲流图片上 */
        for (int x = 0; x < matrix_width; x++) {
            for (int y = 0; y < matrix_height; y++) {
                /** 通过x、y坐标获取一点的颜色 true: 黑色  false: 白色 */
                int rgb = matrix.get(x, y) ? 0x000000 : 0xFFFFFF;
                image.setRGB(x, y, rgb);
            }
        }

        /** 获取公司logo图片 */
        BufferedImage logo = ImageIO.read(new ClassPathResource("static/img/123.jpg").getInputStream());
        /** 获取缓冲流图片的画笔 */
        Graphics2D g = (Graphics2D) image.getGraphics();
        /** 在二维码图片中间绘制公司logo */
        g.drawImage(logo, (matrix_width - LOGO_WIDTH) / 2,
                (matrix_height - LOGO_HEIGHT) / 2, LOGO_WIDTH, LOGO_HEIGHT, null);

        /** 设置画笔的颜色 */
        g.setColor(Color.WHITE);
        /** 设置画笔的粗细 */
        g.setStroke(new BasicStroke(5.0f));
        /** 设置消除锯齿 */
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        /** 绘制圆角矩形 */
        g.drawRoundRect((matrix_width - LOGO_WIDTH) / 2, (matrix_height - LOGO_HEIGHT) / 2,
                LOGO_WIDTH, LOGO_HEIGHT, 10, 10);
        return image;
    }

    // 二维码和图片的合成
    public static final void combineCodeAndPicToFile() {
        long starttime = System.currentTimeMillis();
        System.out.println("开始合成:" + starttime);
        try {
            //背景图
            //BufferedImage big = ImageIO.read(new File(backPicPath));
            BufferedImage big = ImageIO.read(new ClassPathResource("static/img/456.jpg").getInputStream());
            //二维码的图片
            //url扫二维码显示的内容
            BufferedImage small = execute();
            Graphics2D g = big.createGraphics();  //合成的图片

            //二维码或小图在大图的左上角坐标
            int x = big.getWidth() - small.getWidth()-45; //加是向右,减是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,减是向上
            //将二维码花在背景图上
            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            //结束绘画
            g.dispose();
            //为了保证大图背景不变色,formatName必须为"png"
            ImageIO.write(big, "png", new FileOutputStream("111.jpg"));
            System.out.println("结束合成:" + (System.currentTimeMillis() - starttime) / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //合成base64响应前台图片数据展示
    public static final String combineCodeAndPicToBase64(MultipartFile file, HttpServletResponse response) {
        ImageOutputStream imOut = null;
        try {
            BufferedImage big = ImageIO.read(file.getInputStream());
            // BufferedImage small = ImageIO.read(new File(fillPicPath));
            BufferedImage small = ImgUtil.execute();
            Graphics2D g = big.createGraphics();

            //左下角位置
           /* int x = big.getWidth() - small.getWidth()-45; //加是向右,减是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,减是向上*/

            //右下角位置
           /* int x = 45; //加是向右,减是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,减是向上*/
            //居中位置
            int x = (big.getWidth() - small.getWidth())/2; //加是向右,减是向左
            int y = (big.getHeight() - small.getHeight()-50); //加是向下,减是向上

            g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);
            g.dispose();
            //为了保证大图背景不变色,formatName必须为"png"
            //字节数组流
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            //将图片流转换为字节数组流
            imOut = ImageIO.createImageOutputStream(bs);
            //将合成好的背景图输入到字节数组流中
            ImageIO.write(big, "png", imOut);
            //将字节数组流转换为二进制流
            InputStream in = new ByteArrayInputStream(bs.toByteArray());

            byte[] bytes = new byte[in.available()];
            //读取数组流中的数据
            in.read(bytes);
            //转换为base64数据类型
            String base64 = Base64.getEncoder().encodeToString(bytes);
            System.out.println(base64);

            return "data:image/jpeg;base64," + base64;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        combineCodeAndPicToFile();
    }
}

 

3.更多的合成方式查看此链接https://my.oschina.net/kevin2kelly/blog/2988459

 

 

 

posted @ 2020-08-17 21:49  萧何~  阅读(2277)  评论(0编辑  收藏  举报