Cómo comprimir imágenes en Java

fondo del problema

Cuando la imagen es demasiado grande, hará que la página se congele o incluso informe un error, y ahora las páginas, las interfaces y muchos lugares tienen requisitos de límite máximo para la transmisión de mensajes. Además, no sé si alguna vez te has encontrado una página que representa una imagen base64 relativamente grande, estará muy atascada. Por lo tanto, debemos comprimir las imágenes originales cargadas por los usuarios.


¿Por qué el archivo de imagen se vuelve más grande después de la conversión de codificación base64?

Después de convertir la imagen mediante la codificación base64, el archivo será más grande porque la codificación base64 convertirá cada dato de 3 bytes en datos de 4 bytes, y se agregarán algunos caracteres adicionales durante el proceso de conversión. Estos caracteres adicionales incluyen "=", "+", "/", etc., que no existen en los datos de la imagen original.

Entonces, cuando codificamos la imagen en base64, hace que los datos sean más grandes porque necesita más caracteres para representar los mismos datos originales.

Además, el uso de la codificación base64 también ralentizará la velocidad de transmisión de la red, porque los mismos datos necesitan transmitir más caracteres. Por lo tanto, se recomienda utilizar datos binarios sin procesar en lugar de la codificación base64 cuando es necesario transferir grandes cantidades de datos.


 

solución

1. Lea primero la imagen de origen

        nuevo ImgCompress(srcFilePath);

2. Realizar la compresión de imágenes

        redimensionar(int w, int h, String toPic)

3. Las herramientas del código fuente son las siguientes:

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();
	}
}

Observación

Aquí usamos el paquete de dependencia bajo jdk

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

¿Por qué no se puede empaquetar el paquete bajo jdk cuando se empaqueta maven?

Si su proyecto maven se basa en paquetes bajo JDK, pero estos paquetes no están empaquetados cuando se empaquetan, puede deberse a que maven solo empaqueta los paquetes jar de los que depende el proyecto de forma predeterminada, y los paquetes bajo JDK se consideran dependencias de nivel de sistema no agregarse automáticamente al frasco empaquetado.

Para resolver este problema, existen dos métodos comunes:

1. Introducir dependencias maven de paquetes JDK
Puede agregar dependencias similares a las siguientes a pom.xml e importar paquetes bajo JDK en proyectos maven, para que puedan empaquetarse:

<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. Agregue paquetes JDK manualmente
Si no desea introducir dependencias, también puede agregar paquetes manualmente bajo el JDK al archivo jar empaquetado, y puede agregar los siguientes parámetros al comando del paquete maven:

mvn package -Dmaven.compiler.includeJavaxPackages=true

De esta forma, los paquetes bajo el JDK se incluirán en el empaquetado.


Cuando maven está empaquetando, le indicará que no se puede encontrar el paquete. Aquí debemos agregar un elemento de configuración de dependencia de empaque en el archivo POM de maven.

<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>

 Las ubicaciones añadidas son las siguientes: 

 Contenido adicional: la forma de juzgar el tamaño del archivo por Jquery front-end y Java de fondo.

Interfaz:
var fileSize = $("#"+fileId)[0].files[0].size/(1024*1024);
console.log("上传文件大小:"+fileSize+"M");

La variable anterior fileId  es el valor de identificación del cuadro de entrada del archivo.

extremo posterior:
/**
     * 判断文件大小处于限制内
     *
     * @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;
  }

Simplemente use la clase de herramienta directamente, el código es simple y claro, y no hay mucho que explicar y anotar.

Supongo que te gusta

Origin blog.csdn.net/weixin_36754290/article/details/131381415
Recomendado
Clasificación