Java 中圖片壓縮處理的解決方案
問(wèn)題背景
圖片過(guò)大時(shí),會(huì)造成頁(yè)面卡頓甚至于報(bào)錯(cuò),而且現(xiàn)在頁(yè)面,接口,很多地兒都有報(bào)文傳輸?shù)淖畲笙拗埔螅硗獠恢栏魑挥袥](méi)有遇到過(guò)頁(yè)面渲染比較大的 base64 圖片時(shí),會(huì)非常的卡頓。所以,我們必須對(duì)用戶上傳的原始圖片進(jìn)行壓縮處理。
為何圖片經(jīng)過(guò) base64 編碼轉(zhuǎn)換后文件會(huì)變大?
圖片經(jīng)過(guò)base64編碼轉(zhuǎn)換后,文件會(huì)變大的原因是因?yàn)閎ase64編碼會(huì)將每個(gè)3字節(jié)的數(shù)據(jù)轉(zhuǎn)換成4字節(jié)的數(shù)據(jù),并且在轉(zhuǎn)換的過(guò)程中還會(huì)添加一些額外的字符。這些額外的字符包括"="、"+"、"/"等,它們?cè)谠嫉膱D片數(shù)據(jù)中是不存在的。
因此,當(dāng)我們將圖片進(jìn)行base64編碼后,會(huì)使得數(shù)據(jù)變得更大,因?yàn)樗枰嗟淖址麃?lái)表示相同的原始數(shù)據(jù)。
另外,使用base64編碼也會(huì)導(dǎo)致網(wǎng)絡(luò)傳輸速度變慢,因?yàn)橄嗤臄?shù)據(jù)需要傳輸更多的字符。因此,在需要傳輸大量數(shù)據(jù)的情況下,建議使用原始的二進(jìn)制數(shù)據(jù),而不是進(jìn)行base64編碼。
解決方案
1、先讀取源圖片
new ImgCompress(srcFilePath);
2、進(jìn)行圖片壓縮
resize(int w, int h, String toPic)
3、源碼工具類如下:
package com.example.util;
import java.awt.image.BufferedImage;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 圖片壓縮
* @author 86183
*
*/
@SuppressWarnings("restriction")
public class ImgCompress {
static BufferedImage img = null;
public static void main(String[] args) throws IOException {
String fromPic = "C:\\Users\\86183\\Pictures\\兒童節(jié)插畫(huà)手繪人物.png";
String toPic = "C:\\Users\\86183\\Pictures\\兒童節(jié)插畫(huà)手繪人物_min.png";
ImgCompress imgCom = new ImgCompress(fromPic );
imgCom.resize(400, 400, toPic);
}
/**
* 構(gòu)造函數(shù)
*/
public ImgCompress(String fileName) throws IOException {
File file = new File(fileName);// 讀入文件
img = ImageIO.read(file); // 構(gòu)造Image對(duì)象
}
/**
* 強(qiáng)制壓縮/放大圖片到固定的大小
*
* @param w int 新寬度
* @param h int 新高度
*/
public void resize(int w, int h, String toPic) throws IOException {
// SCALE_SMOOTH 的縮略算法 生成縮略圖片的平滑度的 優(yōu)先級(jí)比速度高 生成的圖片質(zhì)量比較好 但速度慢
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
image.getGraphics().drawImage(img, 0, 0, w, h, null); // 繪制縮小后的圖
File destFile = new File(toPic);
FileOutputStream out = new FileOutputStream(destFile); // 輸出到文件流
// 可以正常實(shí)現(xiàn)bmp、png、gif轉(zhuǎn)jpg
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image); // JPEG編碼
out.close();
}
}備注
這里我們用到了 jdk 下的依賴包
import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder;
那 maven 打包時(shí) 為何 jdk 下的包打包不進(jìn)去?
如果你的maven項(xiàng)目中依賴了JDK下的包,但是在打包時(shí)這些包沒(méi)有被打包進(jìn)去,可能是因?yàn)閙aven默認(rèn)只會(huì)把項(xiàng)目中依賴的jar包打包進(jìn)去,而JDK下的包被認(rèn)為是系統(tǒng)級(jí)別的依賴,不會(huì)自動(dòng)加入打包的jar中。
為了解決這個(gè)問(wèn)題,有兩種常用的方法:
1. 引入JDK包的maven依賴你可以在pom.xml中加入類似下面的依賴,把JDK下的包引入到maven項(xiàng)目中,這樣就能夠被打包進(jìn)去了:
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${java.home}/lib/tools.jar</systemPath>
</dependency>2. 手動(dòng)添加JDK包如果不想引入依賴,也可以手動(dòng)將JDK下的包添加到打包的jar文件中,可以在maven打包命令中加入以下參數(shù):
mvn package -Dmaven.compiler.includeJavaxPackages=true
這樣打包時(shí)就會(huì)包含JDK下的包了。
maven 打包時(shí),會(huì)提示找不到該包,這里我們需要在 maven 的 POM 文件里添加一個(gè)打包依賴的設(shè)置項(xiàng)。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>添加的位置如下:

附加內(nèi)容:前端 Jquery 和 后臺(tái) Java 判斷文件大小的方式。 前端:
var fileSize = $("#"+fileId)[0].files[0].size/(1024*1024);
console.log("上傳文件大小:"+fileSize+"M");上面變量 fileId 就是文件 file 輸入框的 id 值。
后端:
/**
* 判斷文件大小處于限制內(nèi)
*
* @param fileLen 文件長(zhǎng)度
* @param fileSize 限制大小
* @param fileUnit 限制的單位(B,K,M,G)
* @return
*/
public static boolean checkFileSizeIsLimit(Long fileLen, int fileSize, String fileUnit) {
double fileSizeCom = 0;
if ("B".equals(fileUnit.toUpperCase())) {
fileSizeCom = (double) fileLen;
} else if ("K".equals(fileUnit.toUpperCase())) {
fileSizeCom = (double) fileLen / 1024;
} else if ("M".equals(fileUnit.toUpperCase())) {
fileSizeCom = (double) fileLen / (1024*1024);
} else if ("G".equals(fileUnit.toUpperCase())) {
fileSizeCom = (double) fileLen / (1024*1024*1024);
}
if (fileSizeCom > fileSize) {
return false;
}
return true;
}直接用工具類即可,代碼簡(jiǎn)單明了,也沒(méi)啥太多可說(shuō)明和備注的。
到此這篇關(guān)于Java 中如何對(duì)圖片進(jìn)行壓縮處理的文章就介紹到這了,更多相關(guān)Java 圖片壓縮處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot2.x使用Jsoup防XSS攻擊的實(shí)現(xiàn)
這篇文章主要介紹了springboot2.x使用Jsoup防XSS攻擊的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
IDEA配置使用Maven Helper插件的方法(詳細(xì)配置)
這篇文章主要介紹了Maven Helper插件IDEA配置使用(詳細(xì)配置),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
詳解spring cloud Feign使用中遇到的問(wèn)題總結(jié)
本篇文章主要介紹了詳解spring cloud Feign使用中遇到的問(wèn)題總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Java字符編碼簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java字符編碼簡(jiǎn)介,本文主要包括以下幾個(gè)方面:編碼基本知識(shí),Java,系統(tǒng)軟件,url,工具軟件等,感興趣的朋友一起看看吧2017-08-08
SpringBoot2.動(dòng)態(tài)@Value的實(shí)現(xiàn)方式
這篇文章主要介紹了SpringBoot2.動(dòng)態(tài)@Value的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java詳解entity轉(zhuǎn)換到vo過(guò)程
這篇文章將用實(shí)例來(lái)和大家介紹一下entity轉(zhuǎn)換到vo的方法過(guò)程。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-06-06
spring-boot集成spring-security的oauth2實(shí)現(xiàn)github登錄網(wǎng)站的示例
本篇文章主要介紹了spring-boot集成spring-security的oauth2實(shí)現(xiàn)github登錄網(wǎng)站的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10
MybatisX 快速開(kāi)發(fā)插件過(guò)程詳解
MybatisX 是一款基于 IDEA 的快速開(kāi)發(fā)插件,方便在使用mybatis以及mybatis-plus開(kāi)始時(shí)簡(jiǎn)化繁瑣的重復(fù)操作,提高開(kāi)發(fā)速率。這篇文章主要介紹了MybatisX 快速開(kāi)發(fā)插件,需要的朋友可以參考下2021-10-10

