java Graphics2D 图片绘写及自定义字体(File转MultipartFile上传返回url)

avatar
作者
猴君
阅读量:0

1. Graphics2D 图片绘写

我的需求是在图片的固定位置绘写固定数值所以比较简单
ImageIO.write(read, “png”, destImageFile); png是文件类型,我这里是固定的

public class ImageText {     private String data;     private float x;     private float y;     private Font font;     private Color color;     public ImageText(String data, Color color) {         this.data = data;         this.color = color;     }     public ImageText(String data, float x, float y, Font font, Color color) {         this.data = data;         this.x = x;         this.y = y;         this.font = font;         this.color = color;     }     public ImageText() {} }  public class DrawUtil {     private static final Logger log = LoggerFactory.getLogger(DrawUtil.class);     /**      * JAVA添加文字水印      * @param srcImageFile  目标图片      * @param destImageFile 结果图片      * @param imageTextList 文字及坐标集合      * @return      */     public static boolean drawText(InputStream srcImageFile, File destImageFile, ArrayList<ImageText> imageTextList) {         try {             //使用ImageIO的read方法读取图片             BufferedImage read = ImageIO.read(srcImageFile);             Graphics2D graphics = read.createGraphics();             // 设置“抗锯齿”的属性             graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);             for (ImageText imageText : imageTextList) {                 // 设置字体类型和大小                 graphics.setFont(imageText.getFont());                 // 设置颜色                 graphics.setColor(imageText.getColor());                 // 添加文字                 graphics.drawString( imageText.getData(), imageText.getX(), imageText.getY());             }             //回收 Graphics 释放资源             graphics.dispose();             //获取到文件的后缀名 //            String fileName = IdUtils.fastSimpleUUID()+".png"; //            String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);             //使用ImageIO的write方法进行输出             ImageIO.write(read, "png", destImageFile);         } catch (IOException e) {             log.error(" watermarkText 图文绘制异常!", e);         }         return true;     } } 

2. 获取自定义字体

字体文件存放在resources/static/OPPOSans-B-2.ttf
fontFile.getInputStream() 使用文件流不然报错 找不到文件
fontFile.getFile()本地执行成功但是上服务器就会报错

/**  * 获取字体文件  */ public static Font getFont(float fontSize) {     Font font = null;     ClassPathResource fontFile = new ClassPathResource("/static/OPPOSans-B-2.ttf");     Font tempFont = null;     try (InputStream in=fontFile.getInputStream();){         tempFont = Font.createFont(Font.TRUETYPE_FONT, in);     } catch (FontFormatException | IOException e) {         log.error(" OPPOSans 字体文件获取失败!", e);     }     assert tempFont != null;     font = tempFont.deriveFont(fontSize);     return font; } 

3. 将File转换MultipartFile

主要是公共的上传文件组件一般使用MultipartFile类型,所有做个转换
MultipartFileDto multipartFileDto = new MultipartFileDto(tempFile.getName(), tempFile.getName(), “image/png”, fileInputStream);
“image/png”, 配置是为了上传MinIO返回的url是直接预览,而不是附件下载
整体图片绘制逻辑是:
先读取resources下的固定图片文件,同时创建临时图片文件作为输出对象,将绘制数据和两个文件相关对象传递给drawText绘画。然后 临时文件将File转换MultipartFile上传MinIO返回url保存,删除临时文件

 import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; public class MultipartFileDto implements MultipartFile {     private final String name;     private String originalFilename;     private String contentType;     private final byte[] content;     public MultipartFileDto(String name, byte[] content) {         this(name, "", null, content);     }     public MultipartFileDto(String name, InputStream contentStream) throws IOException {         this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));     }     public MultipartFileDto(String name, String originalFilename, String contentType, byte[] content) {         this.name = name;         this.originalFilename = (originalFilename != null ? originalFilename : "");         this.contentType = contentType;         this.content = (content != null ? content : new byte[0]);     }     public MultipartFileDto(String name, String originalFilename, String contentType, InputStream contentStream)             throws IOException {          this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));     }     @Override     public String getName() {         return this.name;     }     @Override     public String getOriginalFilename() {         return this.originalFilename;     }     @Override     public String getContentType() {         return this.contentType;     }     @Override     public boolean isEmpty() {         return (this.content.length == 0);     }     @Override     public long getSize() {         return this.content.length;     }     @Override     public byte[] getBytes() throws IOException {         return this.content;     }     @Override     public InputStream getInputStream() throws IOException {         return new ByteArrayInputStream(this.content);     }     @Override     public void transferTo(File dest) throws IOException, IllegalStateException {         FileCopyUtils.copy(this.content, dest);     } } /**  * 新增图片消息   */ private void addImgMsg(JcWechatAccount account, File tempFile) {     //上传图片     try (FileInputStream fileInputStream = new FileInputStream(tempFile);) {         //application/octet-stream 告诉浏览器这是一个附件,浏览器会直接进行下载,而不是预览,只有image/png或者image/jpeg这种的的才会进行预览         MultipartFileDto multipartFileDto = new MultipartFileDto(tempFile.getName(), tempFile.getName(),                 "image/png",                 fileInputStream);         String upload = commonController.upload(multipartFileDto);         addImgMsgText(account, upload,MessageType.IMAGE);     } catch (Exception e) {         log.error(" MultipartFileDto 文件转换失败!", e);     } finally {         //删除临时文件         tempFile.delete();     } }  

4. 若依多Sheet页excel内部生成用于上传,而不是直接下载返回

搜索若依多Sheet页 会找到相关代码 关键方法改造exportExcelManySheet 也是临时文件的方法,记得删除

  /**      * 对list数据源将其里面的数据导入到excel表单      *      * @param list     导出数据集合      * @return 结果      * @throws IOException      */     public File exportExcelManySheet( List<ExcelExp> list) {         File tempFile = null;         FileOutputStream out = null;         try {             String filename = IdUtils.fastSimpleUUID();             //创建临时文件             tempFile = File.createTempFile(filename, ".xlsx");             out = new FileOutputStream(tempFile);             createWorkbook();             for (int index = 0; index < list.size(); index++) {                 this.clazz = list.get(index).getClazz();                 this.init(list.get(index).getDataset(), list.get(index).getFileName(), Type.EXPORT);                 // 取出一共有多少个sheet. //                    double sheetNo = Math.ceil(list.size() / sheetSize);                 createSheetManySheet(index);                 // 产生一行                 Row row = sheet.createRow(0);                 int column = 0;                 // 写入各个字段的列头名称                 for (Object[] os : fields) {                     Excel excel = (Excel) os[1];                     this.createCell(excel, row, column++);                 }                 if (Type.EXPORT.equals(type)) {                     fillExcelData(index, row);                     addStatisticsRow();                 }             }             wb.write(out);            // return tempFile;         } catch (IOException e) {             log.error("导出Excel异常{}", e.getMessage());         } finally {             IOUtils.closeQuietly(wb);             IOUtils.closeQuietly(out);         }         return tempFile;     }  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!