package com.example.caseData.service; import com.example.caseData.config.AppConfig; import com.example.caseData.config.EnvConfig; import com.example.caseData.exception.BusinessException; import com.example.caseData.extend.aliyun.Oss; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.Ellipse2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.io.File; import java.util.Date; import java.util.Objects; @Service public class CertService { @Resource private EnvConfig envConfig; // 生成证书 public String createCert( byte[] avatarPath, String sealPath, String certificateNo, String name, String content, byte[] qrCodeByte ){ try { // 加载背景模板图片 BufferedImage background = ImageIO.read(new File("src/main/resources/static/cert/template.png")); Graphics2D g2d = (Graphics2D) background.getGraphics(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 1. 添加证书编号 Font font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小 g2d.setFont(font); Color customColor = Color.decode("#008983"); g2d.setColor(customColor); g2d.drawString(certificateNo, 285, 570); // 2. 处理并添加头像 BufferedImage avatar = ImageIO.read(new ByteArrayInputStream(avatarPath)); int size = 116; // 目标大小 BufferedImage circleAvatar = createCircularImage(avatar, size); g2d.drawImage(circleAvatar, 465, 620, null); // 3. 添加姓名 font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); g2d.drawString(name, 465, 790); // 4. 添加证书内容 font = new Font("Microsoft YaHei", Font.PLAIN, 48); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); drawStringWithLineBreak(g2d, content, 185, 880, 700, font); // 自动换行绘制文本 // 5. 添加日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); String currentDate = sdf.format(new Date()); font = new Font("Microsoft YaHei", Font.PLAIN, 34); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); g2d.drawString(currentDate, 700, 1277); // 6. 添加印章 BufferedImage seal = ImageIO.read(new File(sealPath)); seal = resize(seal, 264, 264); // 调整印章大小 g2d.drawImage(seal, 645, 1150, null); // 6. 添加小程序二维码 BufferedImage wechatMa = ImageIO.read(new ByteArrayInputStream(qrCodeByte)); wechatMa = resize(wechatMa, 205, 205); // 调整印章大小 g2d.drawImage(wechatMa, 80, 1450, null); // 释放资源 g2d.dispose(); // === 将图片转为 byte[] === ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(background, "png", os); byte[] imageBytes = os.toByteArray(); String fileName = ""; if (Objects.equals(envConfig.getActive(), "dev")){ fileName = "dev/static/images/" + certificateNo + ".png"; }else{ fileName = "prod/static/images/" + certificateNo + ".png"; } boolean uploaded = Oss.putObject(fileName, imageBytes); if (uploaded) { // 返回可访问的 URL(假设你有自定义域名) // 格式:http://你的域名/文件名 return "/" + fileName; } // // 保存最终的证书图片 // ImageIO.write(background, "png", new File("cert.png")); // System.out.println("Certificate generated successfully!"); } catch (IOException e) { throw new BusinessException(e.getMessage()); } return null; } // 生成证书 public String createCertTest( String sealPath, String certificateNo, String name, String content ){ try { // 加载背景模板图片 BufferedImage background = ImageIO.read(new File("src/main/resources/static/cert/template.png")); Graphics2D g2d = (Graphics2D) background.getGraphics(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 1. 添加证书编号 Font font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小 g2d.setFont(font); Color customColor = Color.decode("#008983"); g2d.setColor(customColor); g2d.drawString(certificateNo, 285, 570); // 2. 处理并添加头像 BufferedImage avatar = ImageIO.read(new File("src/main/resources/static/cert/avt.png")); int size = 116; // 目标大小 BufferedImage circleAvatar = createCircularImage(avatar, size); g2d.drawImage(circleAvatar, 465, 620, null); // 3. 添加姓名 font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); g2d.drawString(name, 465, 790); // 4. 添加证书内容 font = new Font("Microsoft YaHei", Font.PLAIN, 48); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); drawStringWithLineBreak(g2d, content, 185, 880, 700, font); // 自动换行绘制文本 // 5. 添加日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); String currentDate = sdf.format(new Date()); font = new Font("Microsoft YaHei", Font.PLAIN, 34); // 可根据模板调整大小 g2d.setFont(font); customColor = Color.decode("#111827"); g2d.setColor(customColor); g2d.drawString(currentDate, 700, 1277); // 6. 添加印章 BufferedImage seal = ImageIO.read(new File(sealPath)); seal = resize(seal, 264, 264); // 调整印章大小 g2d.drawImage(seal, 645, 1150, null); // 6. 添加小程序二维码 BufferedImage wechatMa = ImageIO.read(new File("src/main/resources/static/cert/weChatMa.png")); wechatMa = resize(wechatMa, 205, 205); // 调整印章大小 g2d.drawImage(wechatMa, 80, 1450, null); // 释放资源 g2d.dispose(); // === 将图片转为 byte[] === // ByteArrayOutputStream os = new ByteArrayOutputStream(); // ImageIO.write(background, "png", os); // byte[] imageBytes = os.toByteArray(); // // String fileName = ""; // if (Objects.equals(envConfig.getActive(), "dev")){ // fileName = "dev/static/images/" + certificateNo + ".png"; // }else{ // fileName = "prod/static/images/" + certificateNo + ".png"; // } // // boolean uploaded = Oss.putObject(fileName, imageBytes); // if (uploaded) { // // 返回可访问的 URL(假设你有自定义域名) // // 格式:http://你的域名/文件名 // return "/" + fileName; // } // // 保存最终的证书图片 ImageIO.write(background, "png", new File("cert.png")); System.out.println("Certificate generated successfully!"); } catch (IOException e) { throw new BusinessException(e.getMessage()); } return null; } private static BufferedImage createCircularImage(BufferedImage originalImg, int size) { BufferedImage outputImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = outputImage.createGraphics(); g2.setComposite(AlphaComposite.Src); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(Color.WHITE); g2.fill(new Ellipse2D.Float(0, 0, size, size)); g2.setComposite(AlphaComposite.SrcAtop); g2.drawImage(originalImg.getScaledInstance(size, size, Image.SCALE_SMOOTH), 0, 0, null); g2.dispose(); return outputImage; } private static BufferedImage resize(BufferedImage img, int newW, int newH) { Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH); BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = dimg.createGraphics(); g2d.drawImage(tmp, 0, 0, null); g2d.dispose(); return dimg; } // 绘制带自动换行的字符串 private static void drawStringWithLineBreak(Graphics2D g2d, String text, int x, int y, int maxWidth, Font font) { FontMetrics fm = g2d.getFontMetrics(font); StringBuilder line = new StringBuilder(); String[] words = text.split(""); for (String word : words) { int lineWidth = fm.stringWidth(line + word); if (lineWidth < maxWidth) { line.append(word); } else { g2d.drawString(line.toString(), x, y); y += fm.getHeight(); line = new StringBuilder(word); } } if (!line.isEmpty()) { g2d.drawString(line.toString(), x, y); } } }