首页 > 基础资料 博客日记
Java 中如何对图片进行压缩处理
2023-09-04 17:51:05基础资料围观359次
问题背景
图片过大时,会造成页面卡顿甚至于报错,而且现在页面,接口,很多地儿都有报文传输的最大限制要求,另外不知道各位有没有遇到过页面渲染比较大的 base64 图片时,会非常的卡顿。所以,我们必须对用户上传的原始图片进行压缩处理。
为何图片经过 base64 编码转换后文件会变大?
图片经过base64编码转换后,文件会变大的原因是因为base64编码会将每个3字节的数据转换成4字节的数据,并且在转换的过程中还会添加一些额外的字符。这些额外的字符包括"="、"+"、"/"等,它们在原始的图片数据中是不存在的。
因此,当我们将图片进行base64编码后,会使得数据变得更大,因为它需要更多的字符来表示相同的原始数据。
另外,使用base64编码也会导致网络传输速度变慢,因为相同的数据需要传输更多的字符。因此,在需要传输大量数据的情况下,建议使用原始的二进制数据,而不是进行base64编码。
解决方案
1、先读取源图片
new ImgCompress(srcFilePath);
2、进行图片压缩
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\\儿童节插画手绘人物.png";
String toPic = "C:\\Users\\86183\\Pictures\\儿童节插画手绘人物_min.png";
ImgCompress imgCom = new ImgCompress(fromPic );
imgCom.resize(400, 400, toPic);
}
/**
* 构造函数
*/
public ImgCompress(String fileName) throws IOException {
File file = new File(fileName);// 读入文件
img = ImageIO.read(file); // 构造Image对象
}
/**
* 强制压缩/放大图片到固定的大小
*
* @param w int 新宽度
* @param h int 新高度
*/
public void resize(int w, int h, String toPic) throws IOException {
// SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
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); // 输出到文件流
// 可以正常实现bmp、png、gif转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 打包时 为何 jdk 下的包打包不进去?
如果你的maven项目中依赖了JDK下的包,但是在打包时这些包没有被打包进去,可能是因为maven默认只会把项目中依赖的jar包打包进去,而JDK下的包被认为是系统级别的依赖,不会自动加入打包的jar中。
为了解决这个问题,有两种常用的方法:
1. 引入JDK包的maven依赖
你可以在pom.xml中加入类似下面的依赖,把JDK下的包引入到maven项目中,这样就能够被打包进去了:
<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. 手动添加JDK包
如果不想引入依赖,也可以手动将JDK下的包添加到打包的jar文件中,可以在maven打包命令中加入以下参数:
mvn package -Dmaven.compiler.includeJavaxPackages=true
这样打包时就会包含JDK下的包了。
maven 打包时,会提示找不到该包,这里我们需要在 maven 的 POM 文件里添加一个打包依赖的设置项。
<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>
添加的位置如下:
附加内容:前端 Jquery 和 后台 Java 判断文件大小的方式。
前端:
var fileSize = $("#"+fileId)[0].files[0].size/(1024*1024);
console.log("上传文件大小:"+fileSize+"M");
上面变量 fileId 就是文件 file 输入框的 id 值。
后端:
/**
* 判断文件大小处于限制内
*
* @param fileLen 文件长度
* @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;
}
直接用工具类即可,代码简单明了,也没啥太多可说明和备注的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: