后端java壓縮圖片超詳細圖文教程
1. 圖片壓縮原理
圖片壓縮主要分為兩種類型:有損壓縮和無損壓縮
- 有損壓縮:有損壓縮通過減少圖片中的幾余數(shù)據(jù)來減小圖片文件的大小,但會損失定的圖片質(zhì)量。常見的有損壓縮算法有JPEG、WebP等。
- 無損壓縮:無損壓縮通過優(yōu)化圖片的編碼算法來減小圖片文件的大小,但不會損失任何圖片質(zhì)量。常見的無損壓縮算法有PNG、GIF等
對于需要壓縮至指定大小的需求,我們可以使用有損壓縮算法,并通過不斷嘗試不同的壓縮質(zhì)量來達到目標大小。
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 構(gòu)建Thumbnails.Builder
要使用thumbnailtor,主要使用Thumbnails類,該類采用建造者模式設(shè)計,類中提供了很多返回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 { // 網(wǎng)絡(luò)圖片 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 圖片尺寸&旋轉(zhuǎn)&水印
圖片尺寸控制可以通過width、height,size, forceSize,scale方法控制。
- 處理的圖片必須指定大小,size,width,height,forcesize,scale;不可重復(fù)設(shè)置同一種類型的屬性;有的屬性設(shè)置會互斥;
- width、height,size方法會默認保證原始圖片比例(可以通過設(shè)置keepAspectRatio(false)取消,如果取消則等價于forceSize方法。) 因為收到原始圖片寬高比例的限制,即便設(shè)置了寬高可能也不會引起圖片的尺寸(像素)變化 forceSize則會強制保證寬高,
- scale是設(shè)置圖片寬高比例,不大于1的數(shù)參數(shù)。
- 有以下異常情況要注意:
調(diào)用width和height方法后不能再使用size或者scale方法,否則會拋出異常。
調(diào)用size方法后不能再使用size,scale方法,否則會拋出異常。
調(diào)用scale方法后不能調(diào)用size或keepAspectRatio(boolean) 方法,否則會拋出異常。
3.3.4.1 等比例縮放,控制寬高比(以實際圖 寬高相對長度長的為準)
比如原圖高大于寬,則 size寬設(shè)置失效,否則相反
@Test //等比例縮放, //源:寬:681,長:563,長寬比:0.8267254038 壓縮結(jié)果:寬: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方法,控制旋轉(zhuǎn)
@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) // 旋轉(zhuǎn)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 輸出格式&輸出質(zhì)量
outputFormat控制輸出格式
outputQuality(float quality)設(shè)置輸出質(zhì)量,參數(shù)介于0和1之間,支持小數(shù),數(shù)字越小質(zhì)量越差
@Test /** * outputFormat 方法 * outputFormat(String format)方法用于設(shè)置輸出文件格式。支持的格式可以通過ImageIO.getWriterFormatNames()獲取。 * 常用: JPG jpg tiff bmp BMP gif GIF WBMP png PNG JPEG tif TIF TIFF jpeg wbmp。 * * outputQuality(float quality)設(shè)置輸出質(zhì)量,參數(shù)介于0和1之間,支持小數(shù),數(shù)字越小質(zhì)量越差。 */ public void test15() throws IOException { //參數(shù)是本地文件路徑,支持多參數(shù) Thumbnails.of("C:\\Users\\Administrator\\Desktop\\新建文件夾\\1.png") // 如果不設(shè)置默認跟原圖片一致 .outputFormat("jpg") // 設(shè)置質(zhì)量 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,結(jié)果為thumbnail.picture.jpg。 * SUFFIX_DOT_THUMBNAIL:.thumbnail追加到文件擴展名之前的文件名。例如,給定 picture.jpg,結(jié)果為 picture.thumbnail.jpg * SUFFIX_HYPHEN_THUMBNAIL:-thumbnail追加到文件擴展名之前的文件名。例如,給定 picture.jpg,結(jié)果為 picture-thumbnail.jpg。 * * * public void toFiles(Rename rename) throws IOException // ② * 此方法是①的簡化,等價于①中的第一個參數(shù)destinationDir為空。 * * public void toFiles(Iterable<File> iterable) throws IOException { // ③ * 參數(shù)是Iterable類型,也就是說可以給每個文件設(shè)置輸出文件名。 */
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,如果文件存在,則覆蓋
可設(shè)置 allowOverwrite=false,文件存在,則報錯
3.3.8 輸出到內(nèi)存輸出流(操作內(nèi)存)
ByteArrayOutputStream
ByteArrayInputStream
@Test //輸出到內(nèi)存輸出流 public void toOutPUtStreamTest3() throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream();//內(nèi)存輸出流 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());//轉(zhuǎn)化為內(nèi)存輸入流 Thumbnails.of(inputStream) .size(200,220) .outputQuality(1D) .toFile("F:\\company2\\浙江\\02-需求開發(fā)\\23年12月\\圖片附件上傳問題\\99"); }
總結(jié)
到此這篇關(guān)于后端java壓縮圖片的文章就介紹到這了,更多相關(guān)java壓縮圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot?Security權(quán)限控制自定義failureHandler實例
這篇文章主要為大家介紹了SpringBoot?Security權(quán)限控制自定義failureHandler實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11Springboot整合Netty自定義協(xié)議實現(xiàn)示例詳解
這篇文章主要為大家介紹了Springboot整合Netty自定義協(xié)議實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11springboot的application.yml配置port不生效的解決方案
這篇文章主要介紹了springboot的application.yml配置port不生效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07