开发者

Java使用Thumbnailator实现快速处理图片

目录
  • 1、创建缩略图
  • 2、调整图像大小
  • 3、添加水印
  • 4、添加水印
  • 5、剪切
  • 6、目录下的文件批量操作
  • 7.批量处理图片
  • 8.编写图像工具类

Thumbnailator是一个Java库,用于创建和操作图像缩略图。它提供了简单易用的API,可以轻松地生成缩略图并进行各种操作,如调整大小、旋转、裁剪等。它支持多种图像格式,包括JPEG、PNG和GIF等,并且可以通过链式调用来组合多个操作。Thumbnailator还提供了丰富的文档和示例,以帮助开发者快速上手和使用该库。无论是在Web应用程序还是在桌面应用程序中,Thumbnailator都可以帮助开发者方便地生成和处理图像缩略图。

官网:http://code.google.com/p/thumbnailator/

下面是一些thumbnailator的使用案例:

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

1、创建缩略图

import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.IOException;
 
public class ThumbnailCreator {
    public static void main(String[] args) {
        try {
            Thumbnails.of("input.jpg")
                .size(200, 200)
                .toFile("output.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面的代码将从名为"input.jpg&phpquot;的图像文件创建一个200x200像素的缩略图,并将其保存为"output.jpg"。

2、调整图像大小

import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.IOException;
 
public class ImageResizer {
    public static void main(String[] args) {
        try {
            Thumbnails.of("input.jpg")
                .scale(0.5)
                .outputFormat("png")
                .toFile("output.png");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面的代码将从名为"input.jpg"的图像文件创建一个50%大小的图像,并将其保存为"output.png"。

3、添加水印

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import java.io.File;
import java.io.IOException;
 
public class WatermarkAdder {
    public static void main(String[] args) {
        try {
            Thumbnails.of("input.jpg")
                .scale(0.8)
                .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("watermark.png")), 0.5f)
                .toFile("output.jpg");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面的代码将从名为"input.jpg"的图像文件创建一个80%大小的图像,并在右下角添加一个透明度为0.5的水印图像"watermark.png",并将结果保存为"output.jpg"。

4、添加水印

添加水印也是十分方便,我们示例将水印放在右上角,代码如下:

Thumbnails.of(originalPic)
  .size(2000,1500)
  .watermark(Positions.TOP_RIGHT, ImageIO.read(
    new File(picturePath + "pkslow.size.400X300.jpeg")), 0.5f)
  .toFile(picturePath + "climb-up.watermark.jpeg");

5、剪切

实现剪切代码如下:

Thumbnails.of(originalPic)
  .sourceRegion(Positions.TOP_RIGHT, 1800, 1800)
  .size(400, 400)
  .toFile(picturePath + "climb-up.crop.jpeg");

6、目录下的文件批量操作

这个功能还是非常有用,可以操作目录下的所有图片,并指定文件名输出,如指定前缀,代码如下:

Thumbnails.of(new File("/images/202401/").listFiles())
  .size(400, 400)
  .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

这些示例仅展示了thumbnailator的一部分功能,该库还提供了许多其他功能,例如旋转、裁剪、转换格式等。详细的文档可以在thumbnailator的官方网站上找到。

7.批量处理图片

    /**
     * 批量处理图片
     * @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));
        }
    }
}

8.编写图像工具类

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 保存目标目录
     */
    @Sneakwww.devze.comyThrows
    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(w1, h1), 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();
      www.devze.com  // 设置绘画的区域
        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);
            fo编程客栈r (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;
    }
}

到此这篇关于Java使用Thumbnailator实现快速处理图片的文章就介绍到这了,更多相关Java Thumbnailator处理图片内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜