后端java壓縮圖片超詳細圖文教程
1. 圖片壓縮原理
圖片壓縮主要分為兩種類型:有損壓縮和無損壓縮
- 有損壓縮:有損壓縮通過減少圖片中的幾余數(shù)據(jù)來減小圖片文件的大小,但會損失定的圖片質量。常見的有損壓縮算法有JPEG、WebP等。
- 無損壓縮:無損壓縮通過優(yōu)化圖片的編碼算法來減小圖片文件的大小,但不會損失任何圖片質量。常見的無損壓縮算法有PNG、GIF等
對于需要壓縮至指定大小的需求,我們可以使用有損壓縮算法,并通過不斷嘗試不同的壓縮質量來達到目標大小。
2. ImageIO壓縮(java原生)
3.thumbnailator
3.1引入依賴
<!--圖片壓縮-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.19</version>
</dependency>
3.2 圖片處理步驟

3.3 使用
3.3.1 構建Thumbnails.Builder
要使用thumbnailtor,主要使用Thumbnails類,該類采用建造者模式設計,類中提供了很多返回Builder的靜態(tài)方法。
正如下圖所示,Thumbnails提供了通過字符串圖片地址、File對象、URI對象等方式創(chuàng)建Thumbnails對象的方式。

3.3.2 of方法
有5種重載方法

* =============of方法=============
* scale 代表縮放
* toFile是輸出圖片的方法
*/
@Test
public void test() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.scale(1D)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\3.png");
}
@Test
public void test2() throws IOException {
// File類型的參數(shù),支持多參數(shù)
Thumbnails.of(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png"))
.scale(1D)
.toFile(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\4.png"));
}
@Test
public void test3() throws IOException {
// BufferedImage類型參數(shù)
BufferedImage bufferedImage = ImageIO.read(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png"));
Thumbnails.of(bufferedImage)
.scale(1D)
.toFile(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\5.jpg"));
}
@Test
public void test4() throws IOException {
// FileInputStream類型
InputStream inputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png"));
Thumbnails.of(inputStream)
.scale(1D)
.toFile(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\7.jpg"));
}
@Test
public void test5() throws IOException {
// 網絡圖片
URL url = new URL("https://img1.baidu.com/it/u=1546227440,2897989905&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500");
Thumbnails.of(url)
.scale(1D)
.toFile(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\8.jpg"));
}
3.3.3 fromxxx方法

/**
* =============fromImages方法。批量處理BufferedImage類型的圖片 =============
* scale 代表縮放
* toFile是輸出圖片的方法
*/
@Test
public void test8() throws IOException {
// 參數(shù)是本地文件路徑,支持多參數(shù)
URL url = new URL("https://lmg.jj20.com/up/allimg/1114/0406210Z024/2104060Z024-5-1200.jpg");
URL url2 = new URL("https://lmg.jj20.com/up/allimg/4k/s/02/210924233115O14-0-lp.jpg");
BufferedImage bufferedImage1 = ImageIO.read(url);
BufferedImage bufferedImage2 = ImageIO.read(url2);
List<BufferedImage> list = new ArrayList<>();
list.add(bufferedImage1);
list.add(bufferedImage2);
File file = new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\11.png");
File file2 = new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\22.png");
List<File> files = new ArrayList<>();
files.add(file);
files.add(file2);
Thumbnails.fromImages(list)
.scale(1D)
// 這里必須使用`toFiles`,因為處理的是多圖
.toFiles(files);//Rename.SUFFIX_HYPHEN_THUMBNAIL 這里用這個會報錯,注意.
}
/**
* =============fromInputStreams 方法。批量處理InputStream類型的圖片。 =============
* scale 代表縮放
* toFile是輸出圖片的方法
*/
@Test
public void test9() throws IOException, URISyntaxException {
// 參數(shù)是本地文件路徑,支持多參數(shù)
FileInputStream fileInputStream1 = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\11.png"));
FileInputStream fileInputStream2 = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\22.png"));
List<InputStream> list = new ArrayList<>();
list.add(fileInputStream1);
list.add(fileInputStream2);
File file = new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\111.png");
File file2 = new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\listD\\222.png");
List<File> files = new ArrayList<>();
files.add(file);
files.add(file2);
Thumbnails.fromInputStreams(list)
.scale(1D)
// 這里必須使用`toFiles`,因為處理的是多圖
.toFiles(files);//Rename.SUFFIX_HYPHEN_THUMBNAIL 這里用這個會報錯,注意.
}
3.3.4 圖片尺寸&旋轉&水印
圖片尺寸控制可以通過width、height,size, forceSize,scale方法控制。
- 處理的圖片必須指定大小,size,width,height,forcesize,scale;不可重復設置同一種類型的屬性;有的屬性設置會互斥;
- width、height,size方法會默認保證原始圖片比例(可以通過設置keepAspectRatio(false)取消,如果取消則等價于forceSize方法。) 因為收到原始圖片寬高比例的限制,即便設置了寬高可能也不會引起圖片的尺寸(像素)變化 forceSize則會強制保證寬高,
- scale是設置圖片寬高比例,不大于1的數(shù)參數(shù)。
- 有以下異常情況要注意:
調用width和height方法后不能再使用size或者scale方法,否則會拋出異常。
調用size方法后不能再使用size,scale方法,否則會拋出異常。
調用scale方法后不能調用size或keepAspectRatio(boolean) 方法,否則會拋出異常。
3.3.4.1 等比例縮放,控制寬高比(以實際圖 寬高相對長度長的為準)
比如原圖高大于寬,則 size寬設置失效,否則相反
@Test
//等比例縮放,
//源:寬:681,長:563,長寬比:0.8267254038 壓縮結果:寬:110,高:91,長寬比:0.8272727273
public void test10() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.size(110, 900)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\44.png");
}

3.3.4.2 forceSize方法,強制控制寬高
@Test
//forceSize方法
//源:寬:681,長:563,長寬比:0.8267254038 壓縮到:寬:50,
public void test11() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.forceSize(50, 50)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\test11.png");
}

3.3.4.3 scale方法,寬高壓縮比例
@Test
//scale 方法
//源:寬:681,長:563,長寬比:0.8267254038 壓縮到:寬681/2 ,高563/2,
public void test12() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.scale(0.5)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\test22.png");
}

3.3.4.4 rotate方法,控制旋轉
@Test
//rotate 方法
//源:寬:681,長:563,長寬比:0.8267254038 壓縮到:寬681/2 ,高563/2,
public void test13() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.rotate(30) // 旋轉30度
.scale(0.5)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\test22.png");
}

3.3.4.5 watermark方法,添加水印
@Test
//watermark 方法
public void test14() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
// 水印放到右下角
.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\watermark.jpg")), 0.5f)
.scale(1D)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\test14.png");
}

3.3.5 輸出格式&輸出質量
outputFormat控制輸出格式
outputQuality(float quality)設置輸出質量,參數(shù)介于0和1之間,支持小數(shù),數(shù)字越小質量越差
@Test
/**
* outputFormat 方法
* outputFormat(String format)方法用于設置輸出文件格式。支持的格式可以通過ImageIO.getWriterFormatNames()獲取。
* 常用: JPG jpg tiff bmp BMP gif GIF WBMP png PNG JPEG tif TIF TIFF jpeg wbmp。
*
* outputQuality(float quality)設置輸出質量,參數(shù)介于0和1之間,支持小數(shù),數(shù)字越小質量越差。
*/
public void test15() throws IOException {
//參數(shù)是本地文件路徑,支持多參數(shù)
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
// 如果不設置默認跟原圖片一致
.outputFormat("jpg")
// 設置質量 0.1F-1F之間
.outputQuality(0.1F)
.scale(1D)
.toFile("C:\\Users\\Administrator\\Desktop\\新建文件夾\\test15");
}
3.3.6 輸出
3.3.6.1 輸出到文件
toFile方法,將處理后的文件輸出到指定文件,參數(shù)是文件路徑,不是必須要指定文件后綴。
toFile要求文件讀入的時候必須是單個源,例如如果是Thumbnails.of(“input/logo.jpg”,“input/logo2.jpg”),使用toFile輸出會拋出異常。
- 輸出多文件
批量接入的文件處理完畢后,可以通過toFiles輸出到指定目錄下。
public void toFiles(File destinationDir, Rename rename) throws IOException // ①
public void toFiles(Rename rename) throws IOException // ②
public void toFiles(Iterable iterable) throws IOException { // ③
/**
* public void toFiles(File destinationDir, Rename rename) throws IOException // **********只有file類型輸入才可以用************
* 第一個參數(shù)是文件夾路徑,第二個參數(shù)是文件名處理類型
* NO_CHANGE:文件名不修改。
* PREFIX_DOT_THUMBNAIL:追加 thumbnail.到文件名的開頭。例如,給定 picture.jpg,結果為thumbnail.picture.jpg。
* SUFFIX_DOT_THUMBNAIL:.thumbnail追加到文件擴展名之前的文件名。例如,給定 picture.jpg,結果為 picture.thumbnail.jpg
* SUFFIX_HYPHEN_THUMBNAIL:-thumbnail追加到文件擴展名之前的文件名。例如,給定 picture.jpg,結果為 picture-thumbnail.jpg。
*
*
* public void toFiles(Rename rename) throws IOException // ②
* 此方法是①的簡化,等價于①中的第一個參數(shù)destinationDir為空。
*
* public void toFiles(Iterable<File> iterable) throws IOException { // ③
* 參數(shù)是Iterable類型,也就是說可以給每個文件設置輸出文件名。
*/
3.3.6.1 輸出到單個輸出流&多輸出流
@Test
//輸出到多輸出流
public void toOutPUtStreamTest2() throws IOException {
OutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\新建文件夾\\55.png");
OutputStream os2 = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\新建文件夾\\66.png");
List<OutputStream> list=new ArrayList<>();
list.add(os);
list.add(os2);
Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png")
.scale(1D)
.toOutputStreams(list);
}
toFiles有三種多態(tài)方法
3.3.7 allowOverwrite 覆蓋文件
默認為true,如果文件存在,則覆蓋
可設置 allowOverwrite=false,文件存在,則報錯
3.3.8 輸出到內存輸出流(操作內存)
ByteArrayOutputStream
ByteArrayInputStream
@Test
//輸出到內存輸出流
public void toOutPUtStreamTest3() throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();//內存輸出流
Thumbnails.of("F:\\company2\\浙江\\02-需求開發(fā)\\23年12月\\圖片附件上傳問題\\2.jpg")
.scale(1D)
.toOutputStream(os);
// os.writeTo(new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\新建文件夾\\66.png")));//直接輸出
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());//轉化為內存輸入流
Thumbnails.of(inputStream)
.size(200,220)
.outputQuality(1D)
.toFile("F:\\company2\\浙江\\02-需求開發(fā)\\23年12月\\圖片附件上傳問題\\99");
}總結
到此這篇關于后端java壓縮圖片的文章就介紹到這了,更多相關java壓縮圖片內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot?Security權限控制自定義failureHandler實例
這篇文章主要為大家介紹了SpringBoot?Security權限控制自定義failureHandler實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Springboot整合Netty自定義協(xié)議實現(xiàn)示例詳解
這篇文章主要為大家介紹了Springboot整合Netty自定義協(xié)議實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
springboot的application.yml配置port不生效的解決方案
這篇文章主要介紹了springboot的application.yml配置port不生效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07


