欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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還提供了豐富的文檔和示例,以幫助開(kāi)發(fā)者快速上手和使用該庫(kù)。無(wú)論是在Web應(yīng)用程序還是在桌面應(yīng)用程序中,Thumbnailator都可以幫助開(kāi)發(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());
            }
        });
        // 文件名稱(chēng),文件類(lèi)型,目標(biāo)圖片
        String fileName, fileType;
        BufferedImage newImage;
        for (File file : files) {
            // 文件名稱(chēng)
            fileName = file.getName();
            // 文件類(lèi)型
            fileType = fileName.substring(fileName.indexOf(".") + 1);
            // 生成圖片
            newImage = ImageUtil.getNewImage(file);
            // 保存圖片
            ImageIO.write(newImage, fileType, new File(distDirPath, fileName));
        }
    }
}

8.編寫(xiě)圖像工具類(lèi)

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>圖像處理工具類(lèi)</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());
                }
            });
            // 文件名稱(chēng),文件類(lèi)型,目標(biāo)圖片
            String fileName, fileType;
            BufferedImage newImage;
            for (File file : files) {
                // 文件名稱(chēng)
                fileName = file.getName();
                // 文件類(lèi)型
                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è)置寬高,圖片類(lèi)型
        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è)置繪畫(huà)的區(qū)域
        g2d.setClip(0, 0, width, height);

        // 畫(huà)線條:四條邊上的隨機(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ī)畫(huà)筆顏色
            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è)置寬高,圖片類(lèi)型
        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è)置繪畫(huà)的區(qū)域
        g2d.setClip(0, 0, width, height);
        // 設(shè)置隨機(jī)畫(huà)筆顏色
        g2d.setColor(getRandomColor());
        // 設(shè)置隨機(jī)字體樣式
        g2d.setFont(getRandomFont(fontSize));
        // 畫(huà)字符串
        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) {
        // 字體名稱(chēng)集合
        List<String> fontNames = new ArrayList<>();
        fontNames.add("宋體");
        fontNames.add("微軟雅黑");
        fontNames.add("黑體");

        // 字體類(lèi)型集合
        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);
    }
    
    /**
     * 判斷是否是支持的圖片類(lèi)型
     * @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)文章

  • 去掉IntelliJ IDEA 中 mybatis 對(duì)應(yīng)的 xml 文件警告的教程圖解

    去掉IntelliJ IDEA 中 mybatis 對(duì)應(yīng)的 xml 文件警告的教程圖解

    本文通過(guò)圖文并茂的形式給大家介紹了去掉IntelliJ IDEA 中 mybatis 對(duì)應(yīng)的 xml 文件警告的教程,需要的朋友可以參考下
    2018-06-06
  • Java的“Goto”與標(biāo)簽及使用詳解

    Java的“Goto”與標(biāo)簽及使用詳解

    goto在Java中是一個(gè)保留字,但在語(yǔ)言中并沒(méi)有用到它;Java沒(méi)有g(shù)oto。接下來(lái)通過(guò)本文給大家介紹Java的“Goto”與標(biāo)簽,感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • Java中args參數(shù)數(shù)組的用法說(shuō)明

    Java中args參數(shù)數(shù)組的用法說(shuō)明

    這篇文章主要介紹了Java中args參數(shù)數(shù)組的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • java實(shí)現(xiàn)左旋轉(zhuǎn)字符串

    java實(shí)現(xiàn)左旋轉(zhuǎn)字符串

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)左旋轉(zhuǎn)字符串,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • MybatisPlusInterceptor依賴(lài)變紅如何解決,無(wú)法識(shí)別問(wèn)題

    MybatisPlusInterceptor依賴(lài)變紅如何解決,無(wú)法識(shí)別問(wèn)題

    這篇文章主要介紹了MybatisPlusInterceptor依賴(lài)變紅如何解決,無(wú)法識(shí)別問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Maven忽略單元測(cè)試及打包到Nexus的實(shí)現(xiàn)

    Maven忽略單元測(cè)試及打包到Nexus的實(shí)現(xiàn)

    我們的工程在打包發(fā)布時(shí)候,通常都需要忽略單元測(cè)試,以免因環(huán)境原因,無(wú)法通過(guò)單元測(cè)試而影響發(fā)布,本文主要介紹了Maven忽略單元測(cè)試及打包到Nexus的實(shí)現(xiàn),感興趣的可以了解一下
    2024-04-04
  • 深入解析Java的Hibernate框架中的持久對(duì)象

    深入解析Java的Hibernate框架中的持久對(duì)象

    Hibernate的持久對(duì)象在數(shù)據(jù)庫(kù)數(shù)據(jù)操作中有著重要作用,這里我們就來(lái)深入解析Java的Hibernate框架中的持久對(duì)象,首先必須從理解持久化對(duì)象的生命周期開(kāi)始:
    2016-07-07
  • 分析Java中Map的遍歷性能問(wèn)題

    分析Java中Map的遍歷性能問(wèn)題

    隨著JDK 1.8 Streams API的發(fā)布,使得HashMap擁有了更多的遍歷的方式,但應(yīng)該選擇那種遍歷方式?反而成了一個(gè)問(wèn)題。本文從幾個(gè)方面來(lái)分析 HashMap各種遍歷方式的優(yōu)勢(shì)與不足
    2021-06-06
  • java實(shí)現(xiàn)快速排序算法

    java實(shí)現(xiàn)快速排序算法

    快速排序算法是基于分治策略的另一個(gè)排序算法。其基本思想是:對(duì)輸入的子數(shù)組a[p:r],按以下三個(gè)步驟進(jìn)行排序。 1) 分解(Divide)(2) 遞歸求解(Conquer) (3) 合并(Merge)
    2015-04-04
  • Java?NIO通信基礎(chǔ)示例詳解

    Java?NIO通信基礎(chǔ)示例詳解

    這篇文章主要為大家介紹了Java?NIO通信基礎(chǔ)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論