Generate a QR code according to the content, attach the base map and text and compress it

Preface

The requirement is to provide an interface

[
	{
	"name":"张三",
    "url":"https://www.baidu.com"
	},
    {
	"name":"李四",
    "url":"https://www.baidu.com"
	}
]

Pass in the above data structure, and return a compressed package of a QR code with name as the picture name (if you need to scan the QR code, it will automatically jump).

@PostMapping("/zip")
    public Map gzip(@RequestBody java.util.ArrayList<Map> maps) {
        Map<String, Object> result = new HashMap<>();
        if (CollectionUtil.isEmpty(maps)) {
            result.put("code", 0);
            result.put("msg", "请选择导出的目标");
            result.put("data", null);
            return result;
        }
        System.out.println("本次共导出=====================>"+maps.size()+"条");
        String property = System.getProperty("os.name");
        String filepath;
        if (property.contains("Windows")) {
            filepath = System.getProperty("user.dir") + "\\file\\";
        } else {
            filepath = System.getProperty("user.dir") + "/file/";
        }
        File ditu = null;
        FileUtil.mkdir(filepath);
        //底图
        try {
            ditu = ResourceUtils.getFile("classpath:ditu.jpg");
        } catch (FileNotFoundException e) {
            result.put("code", 0);
            result.put("msg", "找不到底图");
            result.put("data", null);
            return result;
        }
        //文件转化为图片
        //1.遍历maps,将每个元素生成二维码
        List<List<Map>> lists = splitList(maps, 40);//根据每个线程的处理数量平均切割
        CountDownLatch latch = new CountDownLatch(lists.size());
        // 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(lists.size());
        for (int i = 0; i < lists.size(); i++) {
            executorService.execute(new GenerateQrCodeTask(lists.get(i), filepath, ditu, latch));
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        executorService.shutdown();
//        maps.forEach(e-> generate(e,filepath, finalDitu));
        //2.压缩
        File zip = ZipUtil.zip(new File(filepath), Charset.forName("utf-8"));
        //3.上传返回url
        URL url = uploadUtils.uploadFileStream(FileUtil.getInputStream(zip), zip.getName(), 0);
        FileUtil.clean(filepath);
        result.put("code", 20000);
        result.put("msg", failCounts.get()==0?"SUCCESS":failCounts.get()+"条数据没有URL和店名");
        result.put("data", String.valueOf(url));
        failCounts = new AtomicInteger(0);
        return result;
    }

/**
     * 根据用户名和URL生成二维码,扫码后进行跳转
     * 1.将底图等比画到一张图中
     * 2.生成二维码
     * 3.二维码定位
     * 4.定位文字
     * @param map
     * @param targetFile
     * @param ditu
     */
    private void generate(Map map,String targetFile,File ditu) {
        String userName = (String) map.get("name");
        String url = (String) map.get("url");
        File file = new File(targetFile + userName + ".png");
        if (StringUtils.isNullOrEmpty(userName) && StringUtils.isNullOrEmpty(url)) {
            failCounts.incrementAndGet();
            return;
        }
        if (StringUtils.isNullOrEmpty(url)) {
            url = " ";
        }
        Image srcImg = null;
        try {
            srcImg = ImageIO.read(ditu);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取图片的宽
        int srcImgWidth = srcImg.getWidth(null);
        //获取图片的高
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        BufferedImage image = getQR_CODEBufferedImage(url, BarcodeFormat.QR_CODE, 200, 200, getDecodeHintType());
//        BufferedImage qr = QrCodeUtil.generate(url,new QrConfig().setWidth(200).setHeight(200).setMargin(0).setCharset(Charset.forName("utf-8")));
        //新的图片,把带logo的二维码下面加上文字
        BufferedImage outImage = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_4BYTE_ABGR);
        try {
            //画二维码到新的面板
            g.drawImage(image, srcImgWidth/5, srcImgHeight / 5, 200, 200, null);
            if (!StringUtils.isNullOrEmpty(userName)) {
                //画文字到新的面板
                g.setColor(Color.BLACK);
                //字体、字型、字号
                g.setFont(new Font("粗体", Font.PLAIN, 18));
                int strWidth = g.getFontMetrics().stringWidth(userName);
                if (strWidth > srcImgWidth) {
                    //长度过长就换行,换两行
                    String font1 = "";
                    String font2 = "";
                    if (userName.length() > srcImgWidth/(strWidth / userName.length())){
                        //每行最多多少个字进行截取
                        font1 = userName.substring(0,srcImgWidth/(strWidth / userName.length())-1);
                        font2 = userName.substring(srcImgWidth/(strWidth / userName.length()));
                    }
                    //画第一行
                    g.drawString(font1, (srcImgWidth - g.getFontMetrics().stringWidth(font1)) / 2, srcImgHeight / 6 *5);
                    //画第二行,比第一行偏移20
                    g.drawString(font2, (srcImgWidth - g.getFontMetrics().stringWidth(font2)) / 2, srcImgHeight / 6 *5 +20);
                } else {
                    g.drawString(userName, (srcImgWidth - strWidth) / 2, srcImgHeight / 6 *5);
                }
                g.dispose();
            }
            outImage.flush();
            image = outImage;
            g.setColor(Color.BLACK);
            g.dispose();
            bufImg.flush();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.flush();
            baos.flush();
            image = bufImg;
            ImageIO.write(image, "png", baos);
            ImageIO.write(image, "png", file);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

Guess you like

Origin blog.csdn.net/pengyiccb/article/details/114109810