Thumbnailator图像处理

由于项目需要对图片进行处理,特整理了一下。方便后期引用。

功能:实现对图片压缩、旋转、缩放、裁剪、加水印

1、引入依赖

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.17</version>
</dependency>

Thumbnailator是一个Google开源的优秀图片处理的第三方Java类库,处理效果远比Java API的好。Thumbnailator可以使用很少的代码实现图片处理的功能。

2、实现代码

  • 生成文字水印

    根据文字内容和大小,生成图片;

    • 图片背景透明
    • 图片宽高根据字数和字体大小而定
    • 字体、颜色、样式均随机生成
/**
     * 生成文字水印
     *
     * @param text     文字内容
     * @param fontSize 文字大小
     * @return
     */
@SneakyThrows
public static BufferedImage getStringBufferedImage(String text, int fontSize) {
    int width = text.length() * fontSize + 10;
    int height = fontSize + 5;

    // 设置宽高,图片类型
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
    // 获取Graphics2D
    Graphics2D g2d = image.createGraphics();
    // 创建兼容图像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之间的任意alpha值的图像数据
    image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    // 执行
    g2d.dispose();
    // 创建绘制图形
    g2d = image.createGraphics();
    // 设置绘画的区域
    g2d.setClip(0, 0, width, height);
    // 设置随机画笔颜色
    g2d.setColor(getRandomColor());
    // 设置随机字体
    g2d.setFont(getRandomFont(fontSize));
    // 画字符串
    g2d.drawString(text, 5, height - 5);

    return image;
}
  • 生成线条水印

    作用:给目标图片随机添加一些线条;

    特点

    • 背景透明
    • 图片宽高和目标图片一致
    • 线条数量、颜色、位置均随机生成

    实现:四条边上的随机两点连线(两个点不在同一条边上);

    • 四条边分别用1,2,3,4来表示;使用随机数工具在(1,2,3,4)中生成一组(2个)不重复的数,来作为线条起点和终点所在的两条边
    • 确认起点和终点所在边之后,再用随机数来确定 点 在 边 上的位置
/**
     * 生成线条水印
     * ----------------------------
     * 背景透明
     * 指定宽度、高度
     * 线条数量、线条颜色、线条位置随机
     * ----------------------------
     *
     * @param width  宽度
     * @param height 高度
     * @return
     */
public static BufferedImage getLineBufferedImage(int width, int height) {
    // 设置宽高,图片类型
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
    // 获取Graphics2D
    Graphics2D g2d = image.createGraphics();
    // 创建兼容图像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之间的任意alpha值的图像数据
    image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    // 执行
    g2d.dispose();
    // 创建绘制图形
    g2d = image.createGraphics();
    // 设置绘画的区域
    g2d.setClip(0, 0, width, height);

    // 画线条:四条边上的随机两点连线(两个点不在同一条边上)
    // --- 上面边1(x = 0 ~ width,y = 0)
    // --- 右面边2(x = width,y = 0 ~ height)
    // --- 下面边3(x = 0 ~ width,y = height)
    // --- 左面边4(x = 0,y = 0 ~ height)

    // 生成随机数量线条
    Integer num = RandomUtil.getRandomInt(1, 5);
    for (Integer i = 0; i < num; i++) {
        // 设置随机画笔颜色
        g2d.setColor(getRandomColor());

        // 得到随机两条边
        int e1 = 0;
        int e2 = 0;
        Set<Integer> edges = RandomUtil.getRandoms(1, 4, 2);
        for (Integer edge : edges) {
            // 如果e1、e2都已赋值,就退出循环,往下执行
            if (e1 > 0 && e2 > 0) {
                break;
            }
            // 如果e1没有赋值,把当前值赋给e1
            if (e1 == 0) {
                e1 = edge;
                // 退出当前循环,执行下一次循环
                continue;
            }
            // 如果e2没有赋值,把当前值赋给e2
            if (e2 == 0) {
                e2 = edge;
                // 循环体的最后语句,不需要continue
                //continue;
            }
        }

        // 两条边已确定,生成起点、终点
        int p1_x, p1_y;
        int p2_x, p2_y;
        if (e1 > 0 && e2 > 0) {
            // 起点
            switch (e1) {
                    // 上面边(x = 0 ~ width,y = 0)
                case 1:
                    p1_x = RandomUtil.getRandomInt(0, width);
                    p1_y = 0;
                    break;
                    // 右面边2(x = width,y = 0 ~ height)
                case 2:
                    p1_x = width;
                    p1_y = RandomUtil.getRandomInt(0, height);
                    break;
                    // 下面边3(x = 0 ~ width,y = height)
                case 3:
                    p1_x = RandomUtil.getRandomInt(0, width);
                    p1_y = height;
                    break;
                    // 左面边4(x = 0,y = 0 ~ height)
                default:
                    p1_x = 0;
                    p1_y = RandomUtil.getRandomInt(0, height);
            }
            // 终点
            switch (e2) {
                    // 上面边(x = 0 ~ width,y = 0)
                case 1:
                    p2_x = RandomUtil.getRandomInt(0, width);
                    p2_y = 0;
                    break;
                    // 右面边2(x = width,y = 0 ~ height)
                case 2:
                    p2_x = width;
                    p2_y = RandomUtil.getRandomInt(0, height);
                    break;
                    // 下面边3(x = 0 ~ width,y = height)
                case 3:
                    p2_x = RandomUtil.getRandomInt(0, width);
                    p2_y = height;
                    break;
                    // 左面边4(x = 0,y = 0 ~ height)
                default:
                    p2_x = 0;
                    p2_y = RandomUtil.getRandomInt(0, height);
            }

            // 绘制线条
            g2d.drawLine(p1_x, p1_y, p2_x, p2_y);
        }
    }

    return image;
}
  • 给图片添加文字水印
/**
     * 添加文字水印(默认右上角)
     *
     * @param srcImage 原图片
     * @param text     水印内容
     * @param fontSize 水印文字大小
     * @return
     */
@SneakyThrows
public static BufferedImage addStrWater(String srcImage, String text, int fontSize) {
    BufferedImage resImage = Thumbnails.of(srcImage)
        // 不缩放
        .scale(1.0f)
        /**
         * 添加水印
         * -------------
         * 参数1:水印位置
         * 参数2:水印图片
         * 参数3:透明度;0 ~ 1.0f
         * 参数4:嵌入-水印周围的嵌入大小。不能是负数。就是和边界的距离
         */
        .watermark(Positions.TOP_RIGHT, getStringBufferedImage(text, fontSize), 0.5f, 10)
        // 输出质量不变
        .outputQuality(1.0f)
        // 输出格式 (和原图一样)
        .useOriginalFormat()
        // 保存为BufferedImage
        .asBufferedImage();
    return resImage;
}
  • 对图片进行综合处理,生成新图片
    /**
     * 多重处理:
     * 1、随机旋转
     * 2、随机放大
     * 3、裁剪至原尺寸
     * 4、加随机线条水印
     * 5、随机压缩
     */
@SneakyThrows
public static BufferedImage getNewImage(String srcImage) {
    return getNewImage(new File(srcImage));
}    

/**
     * 多重处理:
     * 1、随机旋转
     * 2、随机放大
     * 3、裁剪至原尺寸
     * 4、加随机线条水印
     * 5、随机压缩
     */
@SneakyThrows
public static BufferedImage getNewImage(File srcFile) {
    // 处理前
    BufferedImage img1 = ImageIO.read(srcFile);
    int w1 = img1.getWidth();
    int h1 = img1.getHeight();

    // 图片操作
    // --- 1、旋转、放大
    BufferedImage img2 = Thumbnails.of(img1)
        // 旋转;
        // 角度: 正数:顺时针 负数:逆时针
        .rotate(RandomUtil.getRandomDouble(-0.5, 0.5))
        // 缩放比例
        .scale(RandomUtil.getRandomDouble(1.0, 1.05))
        // 输出格式 (和原图一样)
        .useOriginalFormat()
        // 处理后存为BufferedImage对象
        .asBufferedImage();

    // 旋转、放大后图片尺寸
    int w2 = img2.getWidth();
    int h2 = img2.getHeight();

    // --- 2、裁剪、水印、压缩
    // 起点
    int i = (w2 - w1) / 2;
    int j = (h2 - h1) / 2;
    BufferedImage resImage = Thumbnails.of(img2)
        /**
         * 图片裁剪
         * ---------------
         * 图片左上角为(0,0)
         * ---------------
         * 前两个参数定位裁剪起点;
         * 参数1:起点的横坐标
         * 参数2:超点的纵坐标
         * ---------------
         * 后两个参数指定裁剪尺寸
         * 参数3:宽度
         * 参数4:高度
         */
        .sourceRegion(i, j, w1, h1)
        // 裁剪后不缩放
        .scale(1.0f)
        /**
         * 添加水印
         * -------------
         * 参数1:水印位置
         * 参数2:水印图片
         * 参数3:透明度;0 ~ 1.0f
         * 参数4:嵌入-水印周围的嵌入大小。不能是负数。就是和边界的距离
         */
        .watermark(Positions.TOP_LEFT, getLineBufferedImage(w2, h2), 0.5f, 0)
        // 随机压缩(输出质量)
        .outputQuality(RandomUtil.getRandomFloat(0.85f, 1.0f))
        // 输出格式 (和原图一样)
        .useOriginalFormat()
        //.outputFormat("jpg")
        .asBufferedImage();

    return resImage;
}
  • 批量处理图片
    /**
     * 批量处理图片
     * @param srcDirPath 源目录
     * @param distDirPath 保存目标目录
     */
@SneakyThrows
public static void createImages(String srcDirPath, String distDirPath) {
    // 检查目标文件夹是否存在
    File distDir = new File(distDirPath);
    if (!distDir.exists()) {
        distDir.mkdirs();
    }

    // 批量生成
    File srcDir = new File(srcDirPath);
    if (srcDir.isDirectory()) {
        // 得到源目录下的图片:jpg、jpeg、gif、png
        File[] files = srcDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return isSupportImageType(pathname.getPath());
            }
        });
        // 文件名称,文件类型,目标图片
        String fileName, fileType;
        BufferedImage newImage;
        for (File file : files) {
            // 文件名称
            fileName = file.getName();
            // 文件类型
            fileType = fileName.substring(fileName.indexOf(".") + 1);
            // 生成图片
            newImage = ImageUtil.getNewImage(file);
            // 保存图片
            ImageIO.write(newImage, fileType, new File(distDirPath, fileName));
        }
    }
}

图像工具类完整代码

package com.tuwer.utils;

import lombok.SneakyThrows;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>图像处理工具类</p>
 *
 * @author 土味儿
 * Date 2022/6/13
 * @version 1.0
 */
public class ImageUtil {
    /**
     * 批量处理图片
     * @param srcDirPath 源目录
     * @param distDirPath 保存目标目录
     */
    @SneakyThrows
    public static void createImages(String srcDirPath, String distDirPath) {
        // 检查目标文件夹是否存在
        File distDir = new File(distDirPath);
        if (!distDir.exists()) {
            distDir.mkdirs();
        }

        // 批量生成
        File srcDir = new File(srcDirPath);
        if (srcDir.isDirectory()) {
            // 得到源目录下的图片:jpg、jpeg、gif、png
            File[] files = srcDir.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return isSupportImageType(pathname.getPath());
                }
            });
            // 文件名称,文件类型,目标图片
            String fileName, fileType;
            BufferedImage newImage;
            for (File file : files) {
                // 文件名称
                fileName = file.getName();
                // 文件类型
                fileType = fileName.substring(fileName.indexOf(".") + 1);
                // 生成图片
                newImage = ImageUtil.getNewImage(file);
                // 保存图片
                ImageIO.write(newImage, fileType, new File(distDirPath, fileName));
            }
        }
    }
    
    /**
     * 多重处理:
     * 1、随机旋转
     * 2、随机放大
     * 3、裁剪至原尺寸
     * 4、加随机线条水印
     * 5、随机压缩
     */
    @SneakyThrows
    public static BufferedImage getNewImage(String srcImage) {
        return getNewImage(new File(srcImage));
    }
    /**
     * 多重处理:
     * 1、随机旋转
     * 2、随机放大
     * 3、裁剪至原尺寸
     * 4、加随机线条水印
     * 5、随机压缩
     */
    @SneakyThrows
    public static BufferedImage getNewImage(File srcFile) {
        // 处理前
        BufferedImage img1 = ImageIO.read(srcFile);
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();

        // 图片操作
        // --- 1、旋转、放大
        BufferedImage img2 = Thumbnails.of(img1)
                // 旋转;
                // 角度: 正数:顺时针 负数:逆时针
                .rotate(RandomUtil.getRandomDouble(-0.5, 0.5))
                // 缩放比例
                .scale(RandomUtil.getRandomDouble(1.0, 1.05))
                // 使用原格式
                .useOriginalFormat()
                // 处理后存为BufferedImage对象
                .asBufferedImage();

        // 旋转、放大后图片尺寸
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();

        // --- 2、裁剪、水印、压缩
        // 起点
        int i = (w2 - w1) / 2;
        int j = (h2 - h1) / 2;
        BufferedImage resImage = Thumbnails.of(img2)
		        /**
		         * 图片裁剪
		         * ---------------
		         * 图片左上角为(0,0)
		         * ---------------
		         * 前两个参数定位裁剪起点;
		         * 参数1:起点的横坐标
		         * 参数2:超点的纵坐标
		         * ---------------
		         * 后两个参数指定裁剪尺寸
		         * 参数3:宽度
		         * 参数4:高度
		         */
                .sourceRegion(i, j, w1, h1)
                // 裁剪后不缩放
                .scale(1.0f)
                // 加线条水印
                .watermark(Positions.TOP_LEFT, getLineBufferedImage(w2, h2), 0.5f, 0)
                // 随机压缩(输出质量)
                .outputQuality(RandomUtil.getRandomFloat(0.85f, 1.0f))
                // 输出格式
                .useOriginalFormat()
                //.outputFormat("jpg")
                .asBufferedImage();

        return resImage;
    }


    /**
     * 添加文字水印(默认右上角)
     *
     * @param srcImage 原图片
     * @param text     水印内容
     * @param fontSize 水印文字大小
     * @return
     */
    @SneakyThrows
    public static BufferedImage addStrWater(String srcImage, String text, int fontSize) {
        BufferedImage resImage = Thumbnails.of(srcImage)
                // 不缩放
                .scale(1.0f)
                // 加文字水印
                .watermark(Positions.TOP_RIGHT, getStringBufferedImage(text, fontSize), 0.5f, 10)
                // 输出质量不变
                .outputQuality(1.0f)
                // 输出格式
                .useOriginalFormat()
                .asBufferedImage();
        return resImage;
    }

    /**
     * 生成线条图片
     * ----------------------------
     * 背景透明
     * 指定宽度、高度
     * 线条数量、线条颜色、线条位置随机
     * ----------------------------
     *
     * @param width  宽度
     * @param height 高度
     * @return
     */
    public static BufferedImage getLineBufferedImage(int width, int height) {
        // 设置宽高,图片类型
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // 创建兼容图像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之间的任意alpha值的图像数据
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        // 执行
        g2d.dispose();
        // 创建绘制图形
        g2d = image.createGraphics();
        // 设置绘画的区域
        g2d.setClip(0, 0, width, height);

        // 画线条:四条边上的随机两点连线(两个点不在同一条边上)
        // --- 上面边1(x = 0 ~ width,y = 0)
        // --- 右面边2(x = width,y = 0 ~ height)
        // --- 下面边3(x = 0 ~ width,y = height)
        // --- 左面边4(x = 0,y = 0 ~ height)

        // 生成随机数量线条
        Integer num = RandomUtil.getRandomInt(1, 5);
        for (Integer i = 0; i < num; i++) {
            // 设置随机画笔颜色
            g2d.setColor(getRandomColor());

            // 得到随机两条边
            int e1 = 0;
            int e2 = 0;
            Set<Integer> edges = RandomUtil.getRandoms(1, 4, 2);
            for (Integer edge : edges) {
                // 如果e1、e2都已赋值,就退出循环,往下执行
                if (e1 > 0 && e2 > 0) {
                    break;
                }
                // 如果e1没有赋值,把当前值赋给e1
                if (e1 == 0) {
                    e1 = edge;
                    // 退出当前循环,执行下一次循环
                    continue;
                }
                // 如果e2没有赋值,把当前值赋给e2
                if (e2 == 0) {
                    e2 = edge;
                    // 循环体的最后语句,不需要continue
                    //continue;
                }
            }

            // 两条边已确定,生成起点、终点
            int p1_x, p1_y;
            int p2_x, p2_y;
            if (e1 > 0 && e2 > 0) {
                // 起点
                switch (e1) {
                    // 上面边(x = 0 ~ width,y = 0)
                    case 1:
                        p1_x = RandomUtil.getRandomInt(0, width);
                        p1_y = 0;
                        break;
                    // 右面边2(x = width,y = 0 ~ height)
                    case 2:
                        p1_x = width;
                        p1_y = RandomUtil.getRandomInt(0, height);
                        break;
                    // 下面边3(x = 0 ~ width,y = height)
                    case 3:
                        p1_x = RandomUtil.getRandomInt(0, width);
                        p1_y = height;
                        break;
                    // 左面边4(x = 0,y = 0 ~ height)
                    default:
                        p1_x = 0;
                        p1_y = RandomUtil.getRandomInt(0, height);
                }
                // 终点
                switch (e2) {
                    // 上面边(x = 0 ~ width,y = 0)
                    case 1:
                        p2_x = RandomUtil.getRandomInt(0, width);
                        p2_y = 0;
                        break;
                    // 右面边2(x = width,y = 0 ~ height)
                    case 2:
                        p2_x = width;
                        p2_y = RandomUtil.getRandomInt(0, height);
                        break;
                    // 下面边3(x = 0 ~ width,y = height)
                    case 3:
                        p2_x = RandomUtil.getRandomInt(0, width);
                        p2_y = height;
                        break;
                    // 左面边4(x = 0,y = 0 ~ height)
                    default:
                        p2_x = 0;
                        p2_y = RandomUtil.getRandomInt(0, height);
                }

                // 绘制线条
                g2d.drawLine(p1_x, p1_y, p2_x, p2_y);
            }
        }

        return image;
    }

    /**
     * 生成文字图片
     *
     * @param text     文字内容
     * @param fontSize 文字大小
     * @return
     */
    @SneakyThrows
    public static BufferedImage getStringBufferedImage(String text, int fontSize) {
        int width = text.length() * fontSize + 10;
        int height = fontSize + 5;

        // 设置宽高,图片类型
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // 创建兼容图像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之间的任意alpha值的图像数据
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        // 执行
        g2d.dispose();
        // 创建绘制图形
        g2d = image.createGraphics();
        // 设置绘画的区域
        g2d.setClip(0, 0, width, height);
        // 设置随机画笔颜色
        g2d.setColor(getRandomColor());
        // 设置随机字体样式
        g2d.setFont(getRandomFont(fontSize));
        // 画字符串
        g2d.drawString(text, 5, height - 5);

        return image;
    }

    /**
     * 获取随机颜色
     *
     * @return
     */
    private static Color getRandomColor() {
        // 颜色集合
        List<Color> colors = new ArrayList<>();
        colors.add(Color.BLUE);
        colors.add(Color.RED);
        colors.add(Color.GREEN);
        colors.add(Color.ORANGE);
        colors.add(Color.BLACK);
        colors.add(Color.GRAY);
        colors.add(Color.WHITE);

        return colors.get(RandomUtil.getRandomInt(0, colors.size() - 1));
    }

    /**
     * 获取随机字体
     *
     * @param fontSize 字体大小
     * @return
     */
    private static Font getRandomFont(int fontSize) {
        // 字体名称集合
        List<String> fontNames = new ArrayList<>();
        fontNames.add("宋体");
        fontNames.add("微软雅黑");
        fontNames.add("黑体");

        // 字体类型集合
        List<Integer> fontTypes = new ArrayList<>();
        // 普通
        fontTypes.add(Font.PLAIN);
        // 粗体
        fontTypes.add(Font.BOLD);
        // 斜体
        fontTypes.add(Font.ITALIC);

        String fontName = fontNames.get(RandomUtil.getRandomInt(0, fontNames.size() - 1));
        int fontType = fontTypes.get(RandomUtil.getRandomInt(0, fontTypes.size() - 1));

        return new Font(fontName, fontType, fontSize);
    }
    
    /**
     * 判断是否是支持的图片类型
     * @param imageName
     * @return
     */
    private static boolean isSupportImageType(String imageName){
        List<String> imageTypes = new ArrayList<>();
        imageTypes.add(".jpg");
        imageTypes.add(".jpeg");
        imageTypes.add(".gif");
        imageTypes.add(".png");

        String img = imageName.toLowerCase(Locale.ROOT);
        for (String type : imageTypes) {
            if(img.endsWith(type)){
                return true;
            }
        }
        return false;
    }
}

随机工具类完整代码

package com.tuwer.utils;

import java.text.NumberFormat;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

/**
 * <p>随机数工具类</p>
 * @author 土味儿
 * Date 2022/6/13
 * @version 1.0
 */
public class RandomUtil {
    /**
     * 生成一个随机float数(保留小数点后两位)
     * 包含开始位置start
     * 不包含结束位置end
     *
     * @param start 开始位置:可以为负数
     * @param end   结束位置:end > start
     * @return
     */
    public static float getRandomFloat(float start, float end) {
        ThreadLocalRandom r = ThreadLocalRandom.current();
        double n = r.nextDouble(start, end);
        float f = (float) n;
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(2);
        return Float.parseFloat(nf.format(f));
    }

    /**
     * 生成一个随机double数(保留小数点后两位)
     * 包含开始位置start
     * 不包含结束位置end
     *
     * @param start 开始位置:可以为负数
     * @param end   结束位置:end > start
     * @return
     */
    public static double getRandomDouble(double start, double end) {
        ThreadLocalRandom r = ThreadLocalRandom.current();
        double n = r.nextDouble(start, end);
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(2);
        return Double.parseDouble(nf.format(n));
    }

    /**
     * 生成一个随机整数
     * 包含开始位置start、结束位置end
     *
     * @param start 开始位置:可以为负数
     * @param end   结束位置:end > start
     * @return
     */
    public static Integer getRandomInt(int start, int end) {
        ThreadLocalRandom r = ThreadLocalRandom.current();
        return r.nextInt(start, end + 1);
    }

    /**
     * 生成一组不重复随机整数
     * 包含开始位置start、结束位置end
     *
     * @param start 开始位置:可以为负数
     * @param end   结束位置:end > start
     * @param count 数量 >= 0
     * @return
     */
    public static Set<Integer> getRandoms(int start, int end, int count) {
        // 参数有效性检查
        if (start > end || count < 1) {
            count = 0;
        }
        // 结束值 与 开始值 的差(加1)小于 总数量
        if ((end - start + 1) < count) {
            // 如果结束值大于开始值,取最大可以生成的数量;否则为0
            count = (end - start) > 0 ? (end - start) + 1 : 0;
        }

        // 定义存放集合
        Set<Integer> set = new HashSet<>(count);
        if (count > 0) {
            ThreadLocalRandom r = ThreadLocalRandom.current();
            // 一直生成足够数量后再停止
            while (set.size() < count) {
                set.add(r.nextInt(start, end + 1));
            }
        }
        return set;
    }
}

3、测试

在项目resources资源路径下建三个文件夹

Thumbnailator图像处理

准备原图片

Thumbnailator图像处理

  • 生成五张文字水印(水印为png格式,背景透明)
@Test
@SneakyThrows
public void test1() {
    // 得到图片基础路径
    String basePath = System.getProperty("user.dir") + "\\src\\main\\resources\\image\\";
    for (int i = 0; i < 5; i++) {
        String info = "我爱你中国";
        int fontSize = 40;

        BufferedImage image = ImageUtil.getStringBufferedImage(info, fontSize);
        
        // 生成图片
        String distImg = basePath + "water\\" + UUID.randomUUID() + ".png";
        ImageIO.write(image, "png", new File(distImg));
    }
}

Thumbnailator图像处理

  • 生成五张线条水印
@Test
@SneakyThrows
public void test2() {
    // 图片基础路径
    String basePath = System.getProperty("user.dir") + "\\src\\main\\resources\\image\\";
    for (int i = 0; i < 5; i++) {
        int width = 800;
        int height = 800;

        BufferedImage image = ImageUtil.getLineBufferedImage(width, height);

        // 生成图片
        String distImg = basePath + "water\\" + UUID.randomUUID() + ".png";
        ImageIO.write(image, "png", new File(distImg));
    }
}

Thumbnailator图像处理

  • 给原图添加文字水印(生成三张比较)
@Test
@SneakyThrows
public void test3() {
    // 得到图片基础路径
    String basePath = System.getProperty("user.dir") + "\\src\\main\\resources\\image\\";
    // 目标图片
    String srcImg = basePath + "src\\" + "01.jpg";

    for (int i = 0; i < 3; i++) {
        BufferedImage newImage = ImageUtil.addStrWater(srcImg, "我爱你中国", 30);

        // 生成图片路径
        String distImg = basePath + "dist\\" + UUID.randomUUID() + ".jpg";

        ImageIO.write(newImage, "jpg", new File(distImg));
    }
}

Thumbnailator图像处理

Thumbnailator图像处理

  • 对原图综合处理(生成三张比较)

    1. 随机旋转
    2. 随机放大
    3. 裁剪至原尺寸
    4. 加随机线条水印
    5. 随机压缩
@Test
@SneakyThrows
public void test4() {
    // 得到图片基础路径
    String basePath = System.getProperty("user.dir") + "\\src\\main\\resources\\image\\";
    // 目标图片
    String srcImg = basePath + "src\\" + "01.jpg";

    for (int i = 0; i < 3; i++) {
        BufferedImage newImage = ImageUtil.getNewImage(srcImg);

        // 生成图片路径
        String distImg = basePath + "dist\\" + UUID.randomUUID() + ".jpg";

        ImageIO.write(newImage, "jpg", new File(distImg));
    }
}

Thumbnailator图像处理

Thumbnailator图像处理

Thumbnailator图像处理

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年6月15日 上午11:06
下一篇 2022年6月15日

相关推荐