Java使用Thumbnailator實現(xiàn)快速處理圖片
Thumbnailator是一個Java庫,用于創(chuàng)建和操作圖像縮略圖。它提供了簡單易用的API,可以輕松地生成縮略圖并進行各種操作,如調(diào)整大小、旋轉(zhuǎn)、裁剪等。它支持多種圖像格式,包括JPEG、PNG和GIF等,并且可以通過鏈式調(diào)用來組合多個操作。Thumbnailator還提供了豐富的文檔和示例,以幫助開發(fā)者快速上手和使用該庫。無論是在Web應用程序還是在桌面應用程序中,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)換格式等。詳細的文檔可以在thumbnailator的官方網(wǎng)站上找到。
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 保存目標目錄
*/
@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、隨機旋轉(zhuǎn)
* 2、隨機放大
* 3、裁剪至原尺寸
* 4、加隨機線條水印
* 5、隨機壓縮
*/
@SneakyThrows
public static BufferedImage getNewImage(String srcImage) {
return getNewImage(new File(srcImage));
}
/**
* 多重處理:
* 1、隨機旋轉(zhuǎn)
* 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、旋轉(zhuǎn)、放大
BufferedImage img2 = Thumbnails.of(img1)
// 旋轉(zhuǎn);
// 角度: 正數(shù):順時針 負數(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:起點的橫坐標
* 參數(shù)2:超點的縱坐標
* ---------------
* 后兩個參數(shù)指定裁剪尺寸
* 參數(shù)3:寬度
* 參數(shù)4:高度
*/
.sourceRegion(i, j, w1, h1)
// 裁剪后不縮放
.scale(1.0f)
// 加線條水印
.watermark(Positions.TOP_LEFT, getLineBufferedImage(w1, h1), 0.5f, 0)
// 隨機壓縮(輸出質(zhì)量)
.outputQuality(RandomUtil.getRandomFloat(0.85f, 1.0f))
// 輸出格式
.useOriginalFormat()
//.outputFormat("jpg")
.asBufferedImage();
return resImage;
}
/**
* 添加文字水印(默認右上角)
*
* @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ù)量、線條顏色、線條位置隨機
* ----------------------------
*
* @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);
// 畫線條:四條邊上的隨機兩點連線(兩個點不在同一條邊上)
// --- 上面邊1(x = 0 ~ width,y = 0)
// --- 右面邊2(x = width,y = 0 ~ height)
// --- 下面邊3(x = 0 ~ width,y = height)
// --- 左面邊4(x = 0,y = 0 ~ height)
// 生成隨機數(shù)量線條
Integer num = RandomUtil.getRandomInt(1, 5);
for (Integer i = 0; i < num; i++) {
// 設(shè)置隨機畫筆顏色
g2d.setColor(getRandomColor());
// 得到隨機兩條邊
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沒有賦值,把當前值賦給e1
if (e1 == 0) {
e1 = edge;
// 退出當前循環(huán),執(zhí)行下一次循環(huán)
continue;
}
// 如果e2沒有賦值,把當前值賦給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è)置隨機畫筆顏色
g2d.setColor(getRandomColor());
// 設(shè)置隨機字體樣式
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;
}
}
到此這篇關(guān)于Java使用Thumbnailator實現(xiàn)快速處理圖片的文章就介紹到這了,更多相關(guān)Java Thumbnailator處理圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
去掉IntelliJ IDEA 中 mybatis 對應的 xml 文件警告的教程圖解
本文通過圖文并茂的形式給大家介紹了去掉IntelliJ IDEA 中 mybatis 對應的 xml 文件警告的教程,需要的朋友可以參考下2018-06-06
MybatisPlusInterceptor依賴變紅如何解決,無法識別問題
這篇文章主要介紹了MybatisPlusInterceptor依賴變紅如何解決,無法識別問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07

