最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用Thumbnailator實(shí)現(xiàn)快速處理圖片

 更新時(shí)間:2025年04月23日 10:28:11   作者:小筱在線  
它提供了簡(jiǎn)單易用的API,可以輕松地生成縮略圖并進(jìn)行各種操作,Thumbnailator是一個(gè)Java庫(kù),用于創(chuàng)建和操作圖像縮略圖,下面我們就來(lái)看看具體的操作吧

Thumbnailator是一個(gè)Java庫(kù),用于創(chuàng)建和操作圖像縮略圖。它提供了簡(jiǎn)單易用的API,可以輕松地生成縮略圖并進(jìn)行各種操作,如調(diào)整大小、旋轉(zhuǎn)、裁剪等。它支持多種圖像格式,包括JPEG、PNG和GIF等,并且可以通過(guò)鏈?zhǔn)秸{(diào)用來(lái)組合多個(gè)操作。Thumbnailator還提供了豐富的文檔和示例,以幫助開發(fā)者快速上手和使用該庫(kù)。無(wú)論是在Web應(yīng)用程序還是在桌面應(yīng)用程序中,Thumbnailator都可以幫助開發(fā)者方便地生成和處理圖像縮略圖。

官網(wǎng):http://code.google.com/p/thumbnailator/

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

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

1、創(chuàng)建縮略圖

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"的圖像文件創(chuàng)建一個(gè)200x200像素的縮略圖,并將其保存為"output.jpg"。

2、調(diào)整圖像大小

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"的圖像文件創(chuàng)建一個(gè)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"的圖像文件創(chuàng)建一個(gè)80%大小的圖像,并在右下角添加一個(gè)透明度為0.5的水印圖像"watermark.png",并將結(jié)果保存為"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、剪切

實(shí)現(xiàn)剪切代碼如下:

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

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

這個(gè)功能還是非常有用,可以操作目錄下的所有圖片,并指定文件名輸出,如指定前綴,代碼如下:

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

這些示例僅展示了thumbnailator的一部分功能,該庫(kù)還提供了許多其他功能,例如旋轉(zhuǎn)、裁剪、轉(zhuǎn)換格式等。詳細(xì)的文檔可以在thumbnailator的官方網(wǎng)站上找到。

7.批量處理圖片

    /**
     * 批量處理圖片
     * @param srcDirPath 源目錄
     * @param distDirPath 保存目標(biāo)目錄
     */
@SneakyThrows
public static void createImages(String srcDirPath, String distDirPath) {
    // 檢查目標(biāo)文件夾是否存在
    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());
            }
        });
        // 文件名稱,文件類型,目標(biāo)圖片
        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 保存目標(biāo)目錄
     */
    @SneakyThrows
    public static void createImages(String srcDirPath, String distDirPath) {
        // 檢查目標(biāo)文件夾是否存在
        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());
                }
            });
            // 文件名稱,文件類型,目標(biāo)圖片
            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、隨機(jī)旋轉(zhuǎn)
     * 2、隨機(jī)放大
     * 3、裁剪至原尺寸
     * 4、加隨機(jī)線條水印
     * 5、隨機(jī)壓縮
     */
    @SneakyThrows
    public static BufferedImage getNewImage(String srcImage) {
        return getNewImage(new File(srcImage));
    }
    /**
     * 多重處理:
     * 1、隨機(jī)旋轉(zhuǎn)
     * 2、隨機(jī)放大
     * 3、裁剪至原尺寸
     * 4、加隨機(jī)線條水印
     * 5、隨機(jī)壓縮
     */
    @SneakyThrows
    public static BufferedImage getNewImage(File srcFile) {
        // 處理前
        BufferedImage img1 = ImageIO.read(srcFile);
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();

        // 圖片操作
        // --- 1、旋轉(zhuǎn)、放大
        BufferedImage img2 = Thumbnails.of(img1)
                // 旋轉(zhuǎn);
                // 角度: 正數(shù):順時(shí)針 負(fù)數(shù):逆時(shí)針
                .rotate(RandomUtil.getRandomDouble(-0.5, 0.5))
                // 縮放比例
                .scale(RandomUtil.getRandomDouble(1.0, 1.05))
                // 使用原格式
                .useOriginalFormat()
                // 處理后存為BufferedImage對(duì)象
                .asBufferedImage();

        // 旋轉(zhuǎn)、放大后圖片尺寸
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();

        // --- 2、裁剪、水印、壓縮
        // 起點(diǎn)
        int i = (w2 - w1) / 2;
        int j = (h2 - h1) / 2;
        BufferedImage resImage = Thumbnails.of(img2)
		        /**
		         * 圖片裁剪
		         * ---------------
		         * 圖片左上角為(0,0)
		         * ---------------
		         * 前兩個(gè)參數(shù)定位裁剪起點(diǎn);
		         * 參數(shù)1:起點(diǎn)的橫坐標(biāo)
		         * 參數(shù)2:超點(diǎn)的縱坐標(biāo)
		         * ---------------
		         * 后兩個(gè)參數(shù)指定裁剪尺寸
		         * 參數(shù)3:寬度
		         * 參數(shù)4:高度
		         */
                .sourceRegion(i, j, w1, h1)
                // 裁剪后不縮放
                .scale(1.0f)
                // 加線條水印
                .watermark(Positions.TOP_LEFT, getLineBufferedImage(w1, h1), 0.5f, 0)
                // 隨機(jī)壓縮(輸出質(zhì)量)
                .outputQuality(RandomUtil.getRandomFloat(0.85f, 1.0f))
                // 輸出格式
                .useOriginalFormat()
                //.outputFormat("jpg")
                .asBufferedImage();

        return resImage;
    }


    /**
     * 添加文字水?。J(rèn)右上角)
     *
     * @param srcImage 原圖片
     * @param text     水印內(nèi)容
     * @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)
                // 輸出質(zhì)量不變
                .outputQuality(1.0f)
                // 輸出格式
                .useOriginalFormat()
                .asBufferedImage();
        return resImage;
    }

    /**
     * 生成線條圖片
     * ----------------------------
     * 背景透明
     * 指定寬度、高度
     * 線條數(shù)量、線條顏色、線條位置隨機(jī)
     * ----------------------------
     *
     * @param width  寬度
     * @param height 高度
     * @return
     */
    public static BufferedImage getLineBufferedImage(int width, int height) {
        // 設(shè)置寬高,圖片類型
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        // 獲取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // 創(chuàng)建兼容圖像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之間的任意alpha值的圖像數(shù)據(jù)
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        // 執(zhí)行
        g2d.dispose();
        // 創(chuàng)建繪制圖形
        g2d = image.createGraphics();
        // 設(shè)置繪畫的區(qū)域
        g2d.setClip(0, 0, width, height);

        // 畫線條:四條邊上的隨機(jī)兩點(diǎn)連線(兩個(gè)點(diǎn)不在同一條邊上)
        // --- 上面邊1(x = 0 ~ width,y = 0)
        // --- 右面邊2(x = width,y = 0 ~ height)
        // --- 下面邊3(x = 0 ~ width,y = height)
        // --- 左面邊4(x = 0,y = 0 ~ height)

        // 生成隨機(jī)數(shù)量線條
        Integer num = RandomUtil.getRandomInt(1, 5);
        for (Integer i = 0; i < num; i++) {
            // 設(shè)置隨機(jī)畫筆顏色
            g2d.setColor(getRandomColor());

            // 得到隨機(jī)兩條邊
            int e1 = 0;
            int e2 = 0;
            Set<Integer> edges = RandomUtil.getRandoms(1, 4, 2);
            for (Integer edge : edges) {
                // 如果e1、e2都已賦值,就退出循環(huán),往下執(zhí)行
                if (e1 > 0 && e2 > 0) {
                    break;
                }
                // 如果e1沒(méi)有賦值,把當(dāng)前值賦給e1
                if (e1 == 0) {
                    e1 = edge;
                    // 退出當(dāng)前循環(huán),執(zhí)行下一次循環(huán)
                    continue;
                }
                // 如果e2沒(méi)有賦值,把當(dāng)前值賦給e2
                if (e2 == 0) {
                    e2 = edge;
                    // 循環(huán)體的最后語(yǔ)句,不需要continue
                    //continue;
                }
            }

            // 兩條邊已確定,生成起點(diǎn)、終點(diǎn)
            int p1_x, p1_y;
            int p2_x, p2_y;
            if (e1 > 0 && e2 > 0) {
                // 起點(diǎn)
                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);
                }
                // 終點(diǎn)
                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     文字內(nèi)容
     * @param fontSize 文字大小
     * @return
     */
    @SneakyThrows
    public static BufferedImage getStringBufferedImage(String text, int fontSize) {
        int width = text.length() * fontSize + 10;
        int height = fontSize + 5;

        // 設(shè)置寬高,圖片類型
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        // 獲取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // 創(chuàng)建兼容圖像;Transparency.TRANSLUCENT  透明度  TRANSLUCENT 表示包含或可能包含0.0和1.0之間的任意alpha值的圖像數(shù)據(jù)
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        // 執(zhí)行
        g2d.dispose();
        // 創(chuàng)建繪制圖形
        g2d = image.createGraphics();
        // 設(shè)置繪畫的區(qū)域
        g2d.setClip(0, 0, width, height);
        // 設(shè)置隨機(jī)畫筆顏色
        g2d.setColor(getRandomColor());
        // 設(shè)置隨機(jī)字體樣式
        g2d.setFont(getRandomFont(fontSize));
        // 畫字符串
        g2d.drawString(text, 5, height - 5);

        return image;
    }

    /**
     * 獲取隨機(jī)顏色
     *
     * @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));
    }

    /**
     * 獲取隨機(jī)字體
     *
     * @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;
    }
}

到此這篇關(guān)于Java使用Thumbnailator實(shí)現(xiàn)快速處理圖片的文章就介紹到這了,更多相關(guān)Java Thumbnailator處理圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java使用IO流對(duì)數(shù)組排序?qū)嵗v解

    java使用IO流對(duì)數(shù)組排序?qū)嵗v解

    在本篇文章里小編給大家整理的是一篇關(guān)于java使用IO流對(duì)數(shù)組排序?qū)嵗v解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • springmvc實(shí)現(xiàn)json交互-requestBody和responseBody

    springmvc實(shí)現(xiàn)json交互-requestBody和responseBody

    本文主要介紹了springmvc實(shí)現(xiàn)json交互-requestBody和responseBody的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Spring 事務(wù)事件監(jiān)控及實(shí)現(xiàn)原理解析

    Spring 事務(wù)事件監(jiān)控及實(shí)現(xiàn)原理解析

    本文首先會(huì)使用實(shí)例進(jìn)行講解Spring事務(wù)事件是如何使用的,然后會(huì)講解這種使用方式的實(shí)現(xiàn)原理。感興趣的朋友跟隨小編一起看看吧
    2018-09-09
  • SpringBoot中的@EnableConfigurationProperties注解原理及用法

    SpringBoot中的@EnableConfigurationProperties注解原理及用法

    在SpringBoot中,@EnableConfigurationProperties注解是一個(gè)非常有用的注解,它可以用于啟用對(duì)特定配置類的支持,在本文中,我們將深入探討@EnableConfigurationProperties注解,包括它的原理和如何使用,需要的朋友可以參考下
    2023-06-06
  • SpringBoot?@Profile的使用

    SpringBoot?@Profile的使用

    本文主要介紹了SpringBoot?@Profile的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Spring Boot整合RabbitMQ開發(fā)實(shí)戰(zhàn)詳解

    Spring Boot整合RabbitMQ開發(fā)實(shí)戰(zhàn)詳解

    這篇文章主要介紹了Spring Boot整合RabbitMQ開發(fā)實(shí)戰(zhàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • Springboot項(xiàng)目使用html5的video標(biāo)簽完成視頻播放功能

    Springboot項(xiàng)目使用html5的video標(biāo)簽完成視頻播放功能

    這篇文章主要介紹了Springboot項(xiàng)目使用html5的video標(biāo)簽完成視頻播放功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Spring?MVC啟動(dòng)之HandlerMapping作用及實(shí)現(xiàn)詳解

    Spring?MVC啟動(dòng)之HandlerMapping作用及實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Spring?MVC啟動(dòng)之HandlerMapping作用及實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 快速解決idea @Autowired報(bào)紅線問(wèn)題

    快速解決idea @Autowired報(bào)紅線問(wèn)題

    這篇文章主要介紹了快速解決idea @Autowired報(bào)紅線問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • java實(shí)現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印

    java實(shí)現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印

    這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評(píng)論

涟源市| 光山县| 措勤县| 霍城县| 黄大仙区| 衡山县| 桐庐县| 明星| 上虞市| 柯坪县| 阿巴嘎旗| 高阳县| 怀宁县| 仁寿县| 定边县| 金山区| 怀远县| 蒙城县| 新干县| 衡阳县| 保靖县| 黎川县| 溧阳市| 克什克腾旗| 沅陵县| 上思县| 景德镇市| 依兰县| 温州市| 清河县| 顺义区| 宜都市| 车险| 青海省| 京山县| 永济市| 长宁县| 龙江县| 北流市| 临洮县| 晋州市|