• 在图片上指定区域写文字,超过长度自动换行


        public static void main(String[] args) throws IOException {
            BufferedImage bufferedImage = ImageIO.read(new File("/opt/test/imgTest/xmbg.jpeg"));
            String str = "spark系统执行任务异常:error,Null Point Exception,任务状态【失败】,发生时间:2022-06-17 00:00:00,超过90%任务失败,请尽快查看!下面是瞎写的,模拟很多字的情况,打开手机号多少但还是卡的很两三点非,mission fail!!";
            // 指定区域,左对齐
            drawString(bufferedImage.createGraphics(), str, 350, 50, 200, 200);
            ImageIO.write(bufferedImage, "png", new File("/opt/test/imgTest/xmbg-3.jpeg"));
        }
    
        /**
         * 在指定区域写文字,超过长度自动换行
         *
         * @param g2d       Graphics2D类
         * @param text      需要写的字符串
         * @param x         第一行文字x坐标
         * @param y         第一行文字y坐标
         * @param maxWidth  一行最大宽度
         * @param maxHeight 文本可展示的最大高度,如果行数过多,会自动缩小字体
         * @return 行数
         */
        public static TextInfoDto drawString(Graphics2D g2d, String text, int x, int y, int maxWidth, int maxHeight) {
            TextInfoDto textInfoDto = new TextInfoDto();
    
            // 根据规定的最大宽度与高度,自动缩小字体
            fitFontSize(g2d, text, maxWidth, maxHeight);
    
            FontMetrics fontMetrics = g2d.getFontMetrics();
            // 字符串高、宽
            int textHeight = fontMetrics.getHeight();
            int textWidth = fontMetrics.stringWidth(text);
    
            textInfoDto.setWidth(textWidth);
            textInfoDto.setHeight(textHeight);
    
            int lineCount = 0;
            String tempText = text;
            while (textWidth > maxWidth) {
                // 用每个字的宽度累加,计算一行需要多少字
                int lineStrWidth = 0;
                int charCount = 0;
                while (lineStrWidth < maxWidth) {
                    lineStrWidth += fontMetrics.charWidth(tempText.charAt(charCount));
                    charCount++;
                }
    
                String drawText = tempText.substring(0, charCount);
                // 本行文本宽度
                int subTxtWidth = fontMetrics.stringWidth(drawText);
                // 如果字数长度不够就加点
                while (subTxtWidth < maxWidth && charCount < tempText.length()) {
                    charCount++;
                    drawText = tempText.substring(0, charCount);
                    subTxtWidth = fontMetrics.stringWidth(drawText);
                }
                // 如果字数长度超了就减点
                while (subTxtWidth > maxWidth) {
                    charCount--;
                    drawText = tempText.substring(0, charCount);
                    subTxtWidth = fontMetrics.stringWidth(drawText);
                }
                lineCount++;
                g2d.drawString(drawText, x, y);
                if (charCount >= tempText.length()) {
                    tempText = "";
                    break;
                }
                y += textHeight;
                textWidth = textWidth - subTxtWidth;
                tempText = tempText.substring(charCount);
            }
            if (StringUtils.isNotBlank(tempText)) {
                // 本行长度小于最大宽度,或者最后一行剩下的几个字
                g2d.drawString(tempText, x, y);
                lineCount++;
            }
    
            textInfoDto.setLineCount(lineCount);
            log.info("drawString,textInfoDto={}", textInfoDto);
            return textInfoDto;
        }
    
        /**
         * 根据规定的最大宽度与高度,自动缩小字体
         */
        public static void fitFontSize(Graphics2D g2d, String text, int maxWidth, int maxHeight) {
            FontMetrics fontMetrics = g2d.getFontMetrics();
            // 字符串高、宽
            int textHeight = fontMetrics.getHeight();
            int textWidth = fontMetrics.stringWidth(text);
    
            // 当前字体,写全部字大概需要多少行
            int tmpLineCount = textWidth / maxWidth;
            if (textWidth % maxWidth > 0) {
                tmpLineCount++;
            }
            log.info("原字fontSize=" + fontMetrics.getFont().getSize());
            // 修改字体大小
            while (textHeight * tmpLineCount > maxHeight) {
                Font font = g2d.getFont();
                // 太小就看不清了
                if (font.getSize() <= 8) {
                    break;
                }
                g2d.setFont(new Font(font.getName(), font.getStyle(), font.getSize() - 1));
    
                // 重新获取字体宽高
                fontMetrics = g2d.getFontMetrics();
                textHeight = fontMetrics.getHeight();
                textWidth = fontMetrics.stringWidth(text);
    
                tmpLineCount = textWidth / maxWidth;
                if (textWidth % maxWidth > 0) {
                    tmpLineCount++;
                }
            }
            log.info("修改后fontSize=" + g2d.getFont().getSize());
        }
    
    
    @Data
    public class TextInfoDto {
    
        @ApiModelProperty("文字高度")
        private Integer height;
    
        @ApiModelProperty("文字宽度")
        private Integer width;
    
        @ApiModelProperty("换行行数")
        private Integer lineCount;
    
        @Override
        public String toString() {
            return JSON.toJSONString(this, SerializerFeature.WriteMapNullValue);
        }
    }
  • 相关阅读:
    RocketMQ消息存储(一) mmap零拷贝
    RocketMQ消息存储(二) MappedFile
    RocketMQ(六) 服务端请求与响应的处理 源码分析
    shell脚本中的 [ 和 [[ 的区别(单中括号和双中括号的区别)
    版本回退
    红队字典收集整理
    武装你的 Burp Suite 好用插件分享
    RMI 2021【杂题】
    XXII Open Cup, Grand Prix of IMO【杂题】
    原生渲染自插入列表
  • 原文地址:https://www.cnblogs.com/dong320/p/16385266.html
Copyright © 2020-2023  润新知