Java 中图片压缩处理的解决方案

 更新时间:2023年09月05日 09:53:44   作者:跟着飞哥学编程  
图片经过base64编码转换后,文件会变大的原因是因为base64编码会将每个3字节的数据转换成4字节的数据,并且在转换的过程中还会添加一些额外的字符,这篇文章主要介绍了Java 中如何对图片进行压缩处理,需要的朋友可以参考下

问题背景

图片过大时,会造成页面卡顿甚至于报错,而且现在页面,接口,很多地儿都有报文传输的最大限制要求,另外不知道各位有没有遇到过页面渲染比较大的 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;
  }

直接用工具类即可,代码简单明了,也没啥太多可说明和备注的。

到此这篇关于Java 中如何对图片进行压缩处理的文章就介绍到这了,更多相关Java 图片压缩处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea一招搞定同步所有配置(导入或导出所有配置)

    idea一招搞定同步所有配置(导入或导出所有配置)

    使用intellij idea很长一段时间,软件相关的配置也都按照自己习惯的设置好,如果需要重装软件,还得需要重新设置,本文就详细的介绍了idea 同步所有配置,感兴趣的可以了解一下
    2021-07-07
  • Java的ThreadPoolExecutor业务线程池详细解析

    Java的ThreadPoolExecutor业务线程池详细解析

    这篇文章主要介绍了Java线程池ThreadPoolExecutor详细解析,任务刚开始进来的时候就创建核心线程,核心线程满了会把任务放到阻塞队列,阻塞队列满了之后才会创建空闲线程,达到最大线程数之后,再有任务进来,就只能执行拒绝策略了,需要的朋友可以参考下
    2024-01-01
  • Java之int数组声明与初始化方式

    Java之int数组声明与初始化方式

    这篇文章主要介绍了Java之int数组声明与初始化方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 在Ubuntu系统下安装JDK和Tomcat的教程

    在Ubuntu系统下安装JDK和Tomcat的教程

    这篇文章主要介绍了在Ubuntu系统下安装JDK和Tomcat的教程,这样便是在Linux系统下搭建完整的Java和JSP开发环境,需要的朋友可以参考下
    2015-08-08
  • 利用Java快速查找21位花朵数示例代码

    利用Java快速查找21位花朵数示例代码

    这篇文章主要给大家介绍了关于利用Java快速查找21位花朵数的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习,需要的朋友们下面随着小编来一起学习学习吧。
    2017-10-10
  • Spring中Bean的生命周期实例讲解

    Spring中Bean的生命周期实例讲解

    这篇文章主要介绍了Spring中Bean的生命周期讲解,而Spring中的一个Bean从开始到结束经历很多过程,但总体可以分为六个阶段Bean定义、实例化、属性赋值、初始化、生存期、销毁,需要的朋友可以参考下
    2023-08-08
  • 如何安装jdk及安装MyEclipse的图文教程

    如何安装jdk及安装MyEclipse的图文教程

    这篇文章主要介绍了如何安装jdk及安装MyEclipse的图文教程,需要的朋友可以参考下
    2018-03-03
  • Java中Controller、Service、Dao/Mapper层的区别与用法

    Java中Controller、Service、Dao/Mapper层的区别与用法

    在Java开发中,通常会采用三层架构(或称MVC架构)来划分程序的职责和功能,分别是Controller层、Service层、Dao/Mapper层,本文将详细给大家介绍了三层的区别和用法,需要的朋友可以参考下
    2023-05-05
  • java基础javeSE程序逻辑控制语法

    java基础javeSE程序逻辑控制语法

    主要讲解Java中程序的逻辑控制语句包括 Java中的输入输出方式 顺序结构循环结构等,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-09-09
  • java中输出pdf文件代码分享

    java中输出pdf文件代码分享

    这篇文章主要介绍了java中输出pdf文件代码分享,本文直接给出实现代码,需要的朋友可以参考下
    2015-03-03

最新评论