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

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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值