一个功能简单的图片工具类

Posted justry_deng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个功能简单的图片工具类相关的知识,希望对你有一定的参考价值。

功能说明&演示

1. 文字转换为图片

  • 代码示例(更多用法见重载方法说明)
    /**
     * 文字转换为图片 demo
     */
    public static void main(String[] args) throws Exception 
        BufferedImage bufferedImage = ImgUtil.strConvertToImg(
                Lists.newArrayList(
                        "用户:邓沙利文",
                        "性别:男",
                        "年龄:18岁18天",
                        "爱好:摆烂",
                        "座右铭:我是一只小小小小鸟~嗷!嗷!"
                ), new Font("幼圆", Font.PLAIN, 20),
                new Color(255, 0, 0));
        System.err.println(
                ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png"))
        );
    
    
  • 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)

2. 生成指定大小透明背景的图片,并设置文字

  • 代码示例(更多用法见重载方法说明)
    BufferedImage bufferedImage = ImgUtil.generateImgWithStr(
            Lists.newArrayList(
                    "用户:邓沙利文",
                    "性别:男",
                    "年龄:18岁18天",
                    "爱好:摆烂",
                    "座右铭:我是一只小小小小鸟~嗷!嗷!"
            ),
            // 指定要生成的图片大小
            500, 500,
            // 指定字体及颜色(不指定的话, 默认: 微软雅黑  白色); 当字体大小<=0时,将自动推算字体大小,使其布满图片
            new Font("幼圆", Font.PLAIN, -1), new Color(255, 0, 0));
    System.err.println(
            ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png"))
    );
    
  • 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)

3. 添加水印

  • 代码示例(更多用法见重载方法说明)
    // 可设置字体颜色等,详见重载方法说明; 当字体大小<=0时,将自动推算字体大小,使其布满图片
    BufferedImage bufferedImage = ImgUtil.addWatermark(
            ImageIO.read(new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\熊猫.jpg"))
            , Lists.newArrayList(
                    "用户:邓沙利文",
                    "性别:男",
                    "年龄:18岁18天",
                    "爱好:摆烂",
                    "座右铭:我是一只小小小小鸟~嗷!嗷!"
            ));
    System.err.println(
            ImageIO.write(bufferedImage, "PNG", new File("E:\\\\360MoveData\\\\Users\\\\邓沙利文\\\\Desktop\\\\abc.png"))
    );
    
  • 效果图(图片其实是透明背景的;因为我这里是编辑打开,所以显示的是白色)

使用方式

方式一:直接引入common-ds依赖

common-ds:一个工具类开源包
common-spring:一个spring工具类开源包,集成了common-ds

引入以下依赖后,调用ImgUtil的静态方法即可

<dependency>
    <groupId>com.idea-aedi</groupId>
    <artifactId>common-ds</artifactId>
    <version>2100.5.0</version>
</dependency>

方式二:直接将工具类源码复制到项目中

ImgUtil工具类

import org.apache.commons.lang3.tuple.Triple;

import javax.annotation.Nullable;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 图片工具类
 * <br/>
 * 需要相关依赖:
 * <br/>
 * <dependency>
 *     <groupId>org.apache.commons</groupId>
 *     <artifactId>commons-lang3</artifactId>
 *     <version>3.12.0</version>
 * </dependency>
 * 
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2100.4.6
 */
public class ImgUtil 
    
    /**
     * 中文&中文标点正则
     * <br />
     * [\\u4e00-\\u9fa5]是中文,其余的是中文标点符号
     */
    private static final Pattern CHINESE_PATTERN = Pattern.compile("[\\u4e00-\\u9fa5]|[\\uFF01]|[\\uFF0C-\\uFF0E]|[\\uFF1A-\\uFF1B"
            + "]|[\\uFF1F]|[\\uFF08-\\uFF09]|[\\u3001-\\u3002]|[\\u3010-\\u3011]|[\\u201C-\\u201D]|[\\u2013-\\u2014]|[\\u2018"
            + "-\\u2019]|[\\u2026]|[\\u3008-\\u300F]|[\\u3014-\\u3015]");
    
    /** 行间距(px) */
    public static final int DEFAULT_LINE_SPACING = 5;
    
    /** 左下角 */
    public static final int POSITION_BOTTOM_LEFT = 1;
    
    /** 右下角 */
    public static final int POSITION_BOTTOM_RIGHT = 2;
    
    /** 左上角 */
    public static final int POSITION_TOP_LEFT = 3;
    
    /** 右上角 */
    public static final int POSITION_TOP_RIGHT = 4;
    
    /**
     * 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @return 图片
     * @see ImgUtil#generateImgWithStr(List, int, int, Font, Color, int, int)
     */
    public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight) 
        return generateImgWithStr(contentLines, imgWidth, imgHeight, new Font("微软雅黑", Font.PLAIN, 0),
                new Color(255, 255, 255), DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
    
    
    /**
     * 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @return 图片
     * @see ImgUtil#generateImgWithStr(List, int, int, Font, Color, int, int)
     */
    public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight,
                                                   Font font, Color fontColor) 
        return generateImgWithStr(contentLines, imgWidth, imgHeight, font, fontColor, DEFAULT_LINE_SPACING,
                POSITION_BOTTOM_LEFT);
    
    
    /**
     * 生成带有文字的透明背景的图片 <br/> 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @param contentLines
     *         文本
     * @param imgWidth
     *         图片宽
     * @param imgHeight
     *         图片高
     * @param font
     *         字
     * @param fontColor
     *         字体颜色
     * @param lineSpacing
     *         行间距(单位: 像素)
     * @param contentPosition
     *         文字位置 <br />
     *         @link ImgUtil#POSITION_BOTTOM_LEFT
     *         @link ImgUtil#POSITION_BOTTOM_RIGHT
     *         @link ImgUtil#POSITION_TOP_LEFT
     *         @link ImgUtil#POSITION_TOP_RIGHT
     *
     * @return 图片
     */
    public static BufferedImage generateImgWithStr(List<String> contentLines, int imgWidth, int imgHeight,
                                                   Font font, Color fontColor, int lineSpacing, int contentPosition) 
        if (imgWidth <= 0 || imgHeight <= 0) 
            throw new IllegalArgumentException("imgWidth or imgHeight cannot less than 0 or equal 0.");
        
        
        // step1. 计算文本的行数以及最大长度
        Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(null, contentLines, font);
        int lineCount = triple.getLeft();
        int maxLength;
        
        // step2. 计算字体大小(当字体大小<=0时,将根据图片大小自动计算字体的大小)
        int fontSize = font.getSize();
        if (fontSizeIsIllegal(fontSize)) 
            //noinspection PointlessArithmeticExpression
            double computeHeight = imgHeight * 1 - (lineCount - 1) * lineSpacing;
            //noinspection PointlessArithmeticExpression
            double computeWidth = imgWidth * 1;
            if (computeHeight <= 0 || computeWidth <= 0) 
                throw new IllegalArgumentException("computeHeight or computeWidth is illegal.");
            
            Integer maxLengthLineCharCount = triple.getRight();
            Objects.requireNonNull(maxLengthLineCharCount, "maxLengthLineCharCount should not be null while fontSize "
                    + "<= 0.");
            fontSize = (int) Math.min(computeHeight / lineCount, computeWidth / maxLengthLineCharCount);
            // 文本的最大长度(像素)
            maxLength = fontSize * maxLengthLineCharCount;
         else 
            Integer middle = triple.getMiddle();
            Objects.requireNonNull(middle, "middle should not be null while fontSize > 0.");
            // 文本的最大长度(像素)
            maxLength = middle;
        
        
        // step3. 创建 图形1(图层1) 作为 底色
        BufferedImage bufferedImage = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.clearRect(0, 0, imgWidth, imgHeight);
        bufferedImage = graphics.getDeviceConfiguration().createCompatibleImage(imgWidth, imgHeight,
                Transparency.TRANSLUCENT);
        graphics.dispose();
        
        // step4. 创建 图形2(图层2) 勾画文本
        graphics = bufferedImage.createGraphics();
        graphics.setColor(fontColor);
        graphics.setFont(new Font(font.getName(), font.getStyle(), fontSize));
        // x向右为正, y向下为正
        int startX;
        //  这里发现:Y坐标, 还需要调整(fontSize / 6)后,文字才能正好显示
        int startY;
        switch (contentPosition) 
            case POSITION_BOTTOM_LEFT:
                startX = 0;
                startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
                break;
            case POSITION_BOTTOM_RIGHT:
                startX = imgWidth - maxLength;
                startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
                break;
            case POSITION_TOP_LEFT:
                startX = 0;
                startY = fontSize - (fontSize / 6);
                break;
            case POSITION_TOP_RIGHT:
                startX = imgWidth - maxLength;
                startY = fontSize - (fontSize / 6);
                break;
            default:
                // 默认位于左下角
                startX = 0;
                startY = imgHeight - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
        
        for (int i = 0; i < contentLines.size(); i++) 
            graphics.drawString(contentLines.get(i), startX, startY + i * (fontSize + lineSpacing));
        
        graphics.dispose();
        
        return bufferedImage;
    
    
    /**
     * 将文字转换为透明背景的图片
     *
     * @param contentLines
     *         文本
     * @param fontSize
     *         字体大小(像素)
     *
     * @return 图片
     * @see ImgUtil#strConvertToImg(List, Font, Color, int)
     */
    public static BufferedImage strConvertToImg(List<String> contentLines, int fontSize) 
        return strConvertToImg(contentLines, new Font("微软雅黑", Font.PLAIN, fontSize),
                new Color(255, 255, 255), DEFAULT_LINE_SPACING);
    
    
    /**
     * 将文字转换为透明背景的图片
     *
     * @return 图片
     * @see ImgUtil#strConvertToImg(List, Font, Color, int)
     */
    public static BufferedImage strConvertToImg(List<String> contentLines, Font font, Color fontColor) 
        return strConvertToImg(contentLines, font, fontColor, DEFAULT_LINE_SPACING);
    
    
    /**
     * 将文字转换为透明背景的图片
     *
     * @param contentLines
     *         文本
     * @param font
     *         字
     * @param fontColor
     *         字体颜色
     * @param lineSpacing
     *         行间距(单位: 像素)
     *
     * @return 图片
     */
    public static BufferedImage strConvertToImg(List<String> contentLines, Font font, Color fontColor,
                                                int lineSpacing) 
        int fontSize = font.getSize();
        if (fontSizeIsIllegal(fontSize)) 
            throw new IllegalArgumentException("fontSize cannot less than 0 or equal 0.");
        
        
        // step1. 计算文本的行数以及最大长度
        Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(null, contentLines, font);
        int lineCount = triple.getLeft();
        Integer middle = triple.getMiddle();
        Objects.requireNonNull(middle, "middle should not be null while fontSize > 0.");
        int width = middle;
        
        // step2. 根据字体大小,计算高度
        int height = fontSize * lineCount + (lineCount - 1) * lineSpacing;
        
        // step3.  创建 图形1(图层1) 作为 底色
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.clearRect(0, 0, width, height);
        bufferedImage = graphics.getDeviceConfiguration().createCompatibleImage(width, height,
                Transparency.TRANSLUCENT);
        graphics.dispose();
        
        // step4. 创建 图形2(图层2) 勾画文本
        graphics = bufferedImage.createGraphics();
        graphics.setColor(fontColor);
        graphics.setFont(font);
        // x向右为正, y向下为正
        int startX = 0;
        //  这里发现:还需要 调整(fontSize / 6)后,文字才能正好显示
        int startY = height - fontSize * lineCount - lineSpacing * (lineCount - 1) + fontSize - (fontSize / 6);
        for (int i = 0; i < contentLines.size(); i++) 
            graphics.drawString(contentLines.get(i), startX, startY + i * (fontSize + lineSpacing));
        
        graphics.dispose();
        return bufferedImage;
    
    
    /**
     * 给图片添加水印
     * <br/>
     * 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @return 图片(与入参bufferedImage是同一个对象)
     * @see ImgUtil#addWatermark(BufferedImage, List, Font, Color, int, int)
     */
    public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines) 
        return addWatermark(bufferedImage, contentLines, new Font("微软雅黑", Font.PLAIN, 0), new Color(255, 255, 255), DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
    
    
    /**
     * 给图片添加水印
     * <br/>
     * 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @return 图片(与入参bufferedImage是同一个对象)
     * @see ImgUtil#addWatermark(BufferedImage, List, Font, Color, int, int)
     */
    public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines, Font font, Color fontColor) 
        return addWatermark(bufferedImage, contentLines, font, fontColor, DEFAULT_LINE_SPACING, POSITION_BOTTOM_LEFT);
    
    
    /**
     * 给图片添加水印
     * <br/>
     * 注:若参数font中设置的字体大小<=0,则会自动根据图片设置字体大小
     *
     * @param bufferedImage
     *         图片
     * @param contentLines
     *         文本
     * @param font
     *         字
     * @param fontColor
     *         字体颜色
     * @param lineSpacing
     *         行间距(单位: 像素)
     * @param contentPosition
     *         文字位置 <br />
     *         @link ImgUtil#POSITION_BOTTOM_LEFT
     *         @link ImgUtil#POSITION_BOTTOM_RIGHT
     *         @link ImgUtil#POSITION_TOP_LEFT
     *         @link ImgUtil#POSITION_TOP_RIGHT
     *
     * @return 图片(与入参bufferedImage是同一个对象)
     */
    public static BufferedImage addWatermark(BufferedImage bufferedImage, List<String> contentLines,
                                             Font font, Color fontColor, int lineSpacing, int contentPosition) 
        if (bufferedImage == null) 
            throw new IllegalArgumentException("bufferedImage cannot be null.");
        
        // step1. 计算文本的行数以及最大长度
        Triple<Integer, Integer, Integer> triple = computeLineCountAndMaxLength(bufferedImage, contentLines, font);
        word文档的底色怎么消除?

照片底色怎么改成蓝色 照片底色怎么改成蓝色的

matlab作图导出为PDF去除留白插入latex

PS-白色底色改彩色

MATLAB画图工具中坐标外面的底色是灰的,该如修改?

startuml改背景为白色