Java使用Tinify實(shí)現(xiàn)圖片無(wú)損壓縮(4M無(wú)損壓縮到1M)的方法
引言
在當(dāng)今的數(shù)字化時(shí)代,圖片已成為網(wǎng)站、應(yīng)用和社交媒體中不可或缺的元素。然而,大尺寸的圖片不僅會(huì)增加頁(yè)面或者客戶(hù)端加載時(shí)間,還會(huì)占用大量的存儲(chǔ)空間。為了解決這個(gè)問(wèn)題,可以使用圖片壓縮工具來(lái)減小圖片的尺寸,然后再將壓縮后的圖片上傳至對(duì)象存儲(chǔ)服務(wù)(如阿里云OSS)。本文將詳細(xì)介紹如何利用Tinify壓縮圖片,并將其上傳至OSS,重點(diǎn)介紹圖片壓縮實(shí)現(xiàn)方式。
一、Tinify簡(jiǎn)介
1.1 圖片壓縮的重要性
隨著互聯(lián)網(wǎng)的普及,圖片已成為信息傳遞的重要載體。然而,大尺寸、高分辨率的圖片會(huì)占用大量帶寬和存儲(chǔ)空間,導(dǎo)致網(wǎng)站加載速度變慢。通過(guò)壓縮圖片,可以有效減小文件大小,提高網(wǎng)站性能。
1.2 Tinify概述
Tinify是一個(gè)基于云的圖片壓縮服務(wù),它能夠顯著減小圖片的文件大小,同時(shí)保持圖片的高質(zhì)量。Tin義提供了豐富的API,可以輕松集成到各種項(xiàng)目中。而且還是對(duì)外免費(fèi)開(kāi)放使用的。
1.3 Tinify的使用方式
Tinify提供了兩種主要的圖片壓縮方式:
第一種:源文件直接上傳
直接獲取表單請(qǐng)求的MultipartFile文件,也就是可以從緩沖區(qū)(帶二進(jìn)制字符串)上傳圖像,并獲取壓縮的圖像數(shù)據(jù)。
byte[] sourceData = Files.readAllBytes(Paths.get("unoptimized.jpg"));
byte[] resultData = Tinify.fromBuffer(sourceData).toBuffer();
這種適合OSS上傳,推薦,缺點(diǎn)是會(huì)先把壓縮之后的圖片保存到服務(wù)器,在上傳到oss,可以在上傳之后,刪除圖片。
第二種:圖片URL上傳
只需可以提供一個(gè)URL到您的圖像,而不必上傳它,這種更適合圖片查詢(xún)展示的時(shí)候進(jìn)行壓縮,壓縮之后可以在Source對(duì)象中獲取新的圖片URL。
Source source = Tinify.fromUrl("https://cdn.tinypng.com/images/panda-happy.png");
source.toFile("optimized.jpg");
二、OSS簡(jiǎn)介
阿里云OSS(Object Storage Service)是一種海量、安全、低成本、高可靠的云存儲(chǔ)服務(wù)。用戶(hù)可以通過(guò)RESTful API在任何時(shí)間、任何地點(diǎn)、以任何互聯(lián)網(wǎng)設(shè)備訪問(wèn)OSS上的數(shù)據(jù)。OSS提供了豐富的功能,如文件上傳、下載、刪除、共享等,非常適合用于存儲(chǔ)和管理圖片。這里就不多介紹了,只要做過(guò)圖片上傳,相信大家都知道。
三、實(shí)現(xiàn)流程
通過(guò)上面Tinify壓縮API的介紹,可以看到使用Tinify進(jìn)行圖片壓縮也是比較容易整合的,只要在上傳OSS前對(duì)圖片進(jìn)行壓縮,在獲取壓縮后最新圖片進(jìn)行上傳,對(duì)原有代碼改造也不多。具體流程如下:
3.1 檢查文件大小
判斷上傳的圖片文件大小是否超過(guò)500KB。如果未超過(guò),則不進(jìn)行壓縮,這一塊可以根據(jù)自己業(yè)務(wù)進(jìn)行處理。
3.2 設(shè)置Tinify API密鑰
使用Tinify.setKey(API_KEY)方法設(shè)置Tinify的API密鑰。
3.3 壓縮圖片
使用Tinify.fromBuffer(file.getBytes())方法從文件字節(jié)流創(chuàng)建Tinify的Source對(duì)象。
使用source.toFile(file.getOriginalFilename())方法將壓縮后的圖片保存到服務(wù)器。
讀取服務(wù)器中壓縮后的圖片輸入流,并將其轉(zhuǎn)換為MultipartFile對(duì)象。
3.4 清理臨時(shí)文件
刪除服務(wù)器上臨時(shí)保存的壓縮源文件。
完整實(shí)現(xiàn)流程圖如下:

四、實(shí)現(xiàn)代碼
4.1 引入依賴(lài)
首先,需要在項(xiàng)目中引入Tinify和阿里云OSS的依賴(lài)。
<!-- Tinify -->
<dependency>
<groupId>com.tinify</groupId>
<artifactId>tinify</artifactId>
<version>RELEASE</version>
</dependency>
<!-- 阿里云OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<!-- 阿里云OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.14.1</version>
</dependency>
4.2 配置Tinify API密鑰
在使用Tinify之前,需要先注冊(cè)一個(gè)賬號(hào)并獲取API密鑰,主要是獲取對(duì)應(yīng)的apiKey,這里可以到官網(wǎng)直接申請(qǐng)。
public class TinifyConfig {
public static final String API_KEY = "your_tinify_api_key";
}
4.3 實(shí)現(xiàn)圖片壓縮和上傳功能
以下是實(shí)現(xiàn)圖片壓縮和上傳至OSS的核心代碼:
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.tinify.Tinify;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
public class ImageUploader {
private static final String dir = "your_upload_directory/";
/**
* 圖片上傳
*
* @param file 源文件
* @return 壓縮后圖片的URL
* @throws IOException
*/
public String upload(MultipartFile file) {
String endpoint = OSSClientConstants.endpointMap.get("lden");
OSS ossClient = new OSSClientBuilder().build(endpoint, OSSClientConstants.ACCESS_KEY_ID, OSSClientConstants.ACCESS_KEY_SECRET);
try {
String name = file.getOriginalFilename();
String prefix = name.substring(name.lastIndexOf(".")); // 獲取文件后綴
String filename = dir + UUID.randomUUID() + prefix; // 上傳的文件路徑和文件名
// 壓縮圖片
InputStream is = compressPic(file);
// 上傳阿里OSS
ossClient.putObject(bucket, filename, is);
// 返回圖片上傳URL
return ("https://your_cdn/" + filename);
} catch (Exception e) {
logger.error("上傳發(fā)生錯(cuò)誤", e);
return null;
} finally {
ossClient.shutdown();
}
}
/**
* Tinify壓縮圖片
*
* @param file 源文件
* @return 壓縮圖片流
* @throws IOException
*/
public InputStream compressPic(MultipartFile file) throws IOException {
InputStream is = file.getInputStream();
// 小于 500kb不壓縮,這塊業(yè)務(wù)可以自己決定
if (file.getSize() > 500 * 1024) {
// 設(shè)置Tinify的API密鑰
Tinify.setKey(TinifyConfig.API_KEY);
// 從MultipartFile創(chuàng)建Tinify的Source對(duì)象,壓縮圖片
Source source = Tinify.fromBuffer(file.getBytes());
// 壓縮之后保存到服務(wù)器
source.toFile(file.getOriginalFilename());
// 讀取服務(wù)器中壓縮圖片輸入流
byte[] bytes = Files.readAllBytes(Paths.get(file.getOriginalFilename()));
is = convertToMultipartFile(bytes, file.getOriginalFilename()).getInputStream();
// 刪除壓縮源文件
Files.deleteIfExists(Paths.get(file.getOriginalFilename()));
}
return is;
}
}
4.4 壓縮效果驗(yàn)證
程序運(yùn)行之后,查看日志,可以對(duì)比壓縮前后圖片大小,可以看到4M圖片壓縮之后變成了1M。

或者直接對(duì)比壓縮前后兩張圖片的大小,更加直觀說(shuō)明。
原圖片:

壓縮之后圖片:

4.5 注意事項(xiàng)
- API密鑰安全:請(qǐng)確保Tinify的API密鑰和OSS的訪問(wèn)密鑰安全,不要泄露給他人,可以統(tǒng)一保存到安全的配置文件或數(shù)據(jù)庫(kù)中。
- 異常處理:在實(shí)際應(yīng)用中,需要對(duì)可能出現(xiàn)的異常進(jìn)行詳細(xì)處理,以確保程序的健壯性。
- 文件命名:為了避免文件名沖突,可以使用UUID生成唯一的文件名。
- 壓縮圖片刪除:為了避免占用服務(wù)器內(nèi)存,可以在壓縮之后刪除臨時(shí)保存的壓縮源文件。
五、總結(jié)
通過(guò)本文的介紹,了解了如何利用Tinify壓縮圖片,并將其上傳至阿里云OSS。這種方法不僅可以減小圖片的文件大小,提高頁(yè)面加載速度,還可以節(jié)省存儲(chǔ)空間。希望本文的內(nèi)容對(duì)有所幫助,能夠優(yōu)化Web應(yīng)用中的圖片管理。
以上就是Java使用Tinify實(shí)現(xiàn)圖片無(wú)損壓縮的方法的詳細(xì)內(nèi)容,更多關(guān)于Java Tinify圖片壓縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志
文章介紹了如何通過(guò)動(dòng)態(tài)標(biāo)簽日志實(shí)現(xiàn),解決了部分業(yè)務(wù)代碼在多個(gè)模塊中調(diào)用時(shí)日志無(wú)法直觀看出來(lái)源的問(wèn)題,主要通過(guò)ThreadLocal存儲(chǔ)業(yè)務(wù)標(biāo)簽,并在日志輸出時(shí)插入該標(biāo)簽,實(shí)現(xiàn)日志的動(dòng)態(tài)標(biāo)簽功能,感興趣的朋友一起看看吧2024-12-12
springboot攔截器過(guò)濾token,并返回結(jié)果及異常處理操作
這篇文章主要介紹了springboot攔截器過(guò)濾token,并返回結(jié)果及異常處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
淺談java+內(nèi)存分配及變量存儲(chǔ)位置的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談java+內(nèi)存分配及變量存儲(chǔ)位置的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
MyBatis-Plus 使用枚舉自動(dòng)關(guān)聯(lián)注入
本文主要介紹了MyBatis-Plus 使用枚舉自動(dòng)關(guān)聯(lián)注入,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
mybatis分割字符串并循環(huán),實(shí)現(xiàn)in多個(gè)參數(shù)的操作
這篇文章主要介紹了mybatis分割字符串并循環(huán),實(shí)現(xiàn)in多個(gè)參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
SpringBoot集成Redis及SpringCache緩存管理示例詳解
本文介紹了如何在SpringBoot中集成Redis并使用SpringCache進(jìn)行緩存管理,詳解了Redis的配置、使用以及SpringCache的注解,還闡述了SpringCache的工作原理,包括其AOP實(shí)現(xiàn)和與各種緩存框架的集成,使得開(kāi)發(fā)者可以輕松實(shí)現(xiàn)緩存功能,以提高應(yīng)用性能2024-09-09
使用IDEA創(chuàng)建一個(gè)vert.x項(xiàng)目的方法
這篇文章主要介紹了使用IDEA創(chuàng)建一個(gè)vert.x項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09

