Java使用Thumbnailator實現(xiàn)快速處理圖片
Thumbnailator是一個Java庫,用于創(chuàng)建和操作圖像縮略圖。它提供了簡單易用的API,可以輕松地生成縮略圖并進(jìn)行各種操作,如調(diào)整大小、旋轉(zhuǎn)、裁剪等。它支持多種圖像格式,包括JPEG、PNG和GIF等,并且可以通過鏈?zhǔn)秸{(diào)用來組合多個操作。Thumbnailator還提供了豐富的文檔和示例,以幫助開發(fā)者快速上手和使用該庫。無論是在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)建一個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)建一個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)建一個80%大小的圖像,并在右下角添加一個透明度為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、剪切
實現(xiàn)剪切代碼如下:
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的一部分功能,該庫還提供了許多其他功能,例如旋轉(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ù):順時針 負(fù)數(shù):逆時針 .rotate(RandomUtil.getRandomDouble(-0.5, 0.5)) // 縮放比例 .scale(RandomUtil.getRandomDouble(1.0, 1.05)) // 使用原格式 .useOriginalFormat() // 處理后存為BufferedImage對象 .asBufferedImage(); // 旋轉(zhuǎn)、放大后圖片尺寸 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) * --------------- * 前兩個參數(shù)定位裁剪起點; * 參數(shù)1:起點的橫坐標(biāo) * 參數(shù)2:超點的縱坐標(biāo) * --------------- * 后兩個參數(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ī)兩點連線(兩個點不在同一條邊上) // --- 上面邊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沒有賦值,把當(dāng)前值賦給e1 if (e1 == 0) { e1 = edge; // 退出當(dāng)前循環(huán),執(zhí)行下一次循環(huán) continue; } // 如果e2沒有賦值,把當(dāng)前值賦給e2 if (e2 == 0) { e2 = edge; // 循環(huán)體的最后語句,不需要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 文字內(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實現(xiàn)快速處理圖片的文章就介紹到這了,更多相關(guān)Java Thumbnailator處理圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
去掉IntelliJ IDEA 中 mybatis 對應(yīng)的 xml 文件警告的教程圖解
本文通過圖文并茂的形式給大家介紹了去掉IntelliJ IDEA 中 mybatis 對應(yīng)的 xml 文件警告的教程,需要的朋友可以參考下2018-06-06MybatisPlusInterceptor依賴變紅如何解決,無法識別問題
這篇文章主要介紹了MybatisPlusInterceptor依賴變紅如何解決,無法識別問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07