什么是webp格式?
WebP 格式是一种图像文件格式。
它是由谷歌开发的,旨在提供一种高效的图像压缩方式,同时保持较好的图像质量。WebP 格式具有较小的文件体积,能够在一定程度上减少网络传输的数据量,提升网页加载速度。它支持有损压缩和无损压缩两种模式。
为什么要用webp格式?
- 减小文件大小
- 能显著降低图片文件的体积,节省存储空间。
- 减少网络传输的数据量,降低服务器的带宽压力。
- 提升加载效率
- 更快的加载速度可以改善用户体验。
- 快速加载的图片能让用户在浏览时感觉更流畅。
- 保持较好质量
- 在压缩过程中能较好地保留图像的细节和质量。
话不多说,上代码
首先 spring 三板斧
引入依赖:
因为webp在java中并没有上传到maven中央仓库,只能通过jar手动上传。点我下载文件
手动依赖方案:
<!-- 图片格式转换为webp-->
<dependency><groupId>com.github.nintha</groupId><artifactId>webp-imageio-core</artifactId><version>0.1.3</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/libs/webp-imageio-core-0.1.3.jar</systemPath>
</dependency>
FileUtils
package cn.ideamake.file.common.utils;import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.stream.StreamUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.ideamake.file.aop.MockMultipartFile;
import com.luciad.imageio.webp.WebPWriteParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Date;
import java.util.UUID;@Slf4j
public class FileUtils {/*** 图片文件类型转换为webp格式* @return webp图片*/public static File imagesToWebp(File file){try {String fileType = FileTypeUtil.getType(file);String outputWebpPath;if (!StrUtil.equalsAny(fileType, "jpg", "png", "jpeg")) {return null;}outputWebpPath = "/tmp/" + RandomUtil.randomString(32) + ".webp";// Obtain an image to encode from somewhereBufferedImage image = ImageIO.read(file);// Obtain a WebP ImageWriter instanceImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();// Configure encoding parametersWebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());writeParam.setCompressionMode(WebPWriteParam.MODE_DEFAULT);// Configure the output on the ImageWriterwriter.setOutput(new FileImageOutputStream(new File(outputWebpPath)));// Encodewriter.write(null, new IIOImage(image, null, null), writeParam);return new File(outputWebpPath);} catch (Exception e) {log.error("上传失败", e);return null;}}public static MultipartFile imagesToWebp(MultipartFile multipartFile) throws IOException {File tmpFile = multipartFileToFile(multipartFile, "/tmp/multipartFileToFile", RandomUtil.randomString(32) + "." + FileUtil.getSuffix(multipartFile.getOriginalFilename()));File file = imagesToWebp(tmpFile);return file == null ? multipartFile : new MockMultipartFile(file.getName(), FileUtil.getInputStream(file));}/*** MultipartFile类型文件转File* @return File类型文件*/private static File multipartFileToFile(MultipartFile multipartFile, String filePath, String fileName){File f = null;File dir = new File(filePath);if (!dir.exists() && !dir.isDirectory()) {dir.mkdirs();}if(multipartFile.getSize() <= 0){multipartFile = null;} else {try {InputStream ins = multipartFile.getInputStream();f = new File(filePath + fileName);OutputStream os = Files.newOutputStream(f.toPath());int bytesRead = 0;byte[] buffer = new byte[8192];while ((bytesRead = ins.read(buffer, 0, 8192)) != -1){os.write(buffer, 0, bytesRead);}os.close();ins.close();} catch (IOException e) {log.error("转换file文件失败:{}", e);}}return f;}public static byte[] imagesToWebp(byte[] bytes, String fileName){File file = imagesToWebp(FileUtil.writeBytes(bytes, "/tmp/multipartFileToFile/" + fileName));return file == null ? bytes : FileUtil.readBytes(file);}}
方法可自行重载扩展。
需要返回 MultipartFile 文件格式康我 MockMultipartFile 类
/** Copyright 2002-2018 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package cn.ideamake.file.aop;import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;/*** Mock implementation of the {@link MultipartFile}* interface.**/
public class MockMultipartFile implements MultipartFile {private final String name;private final String originalFilename;@Nullableprivate final String contentType;private final byte[] content;/*** Create a new MockMultipartFile with the given content.* @param name the name of the file* @param content the content of the file*/public MockMultipartFile(String name, @Nullable byte[] content) {this(name, name, null, content);}/*** Create a new MockMultipartFile with the given content.* @param name the name of the file* @param contentStream the content of the file as stream* @throws IOException if reading from the stream failed*/public MockMultipartFile(String name, InputStream contentStream) throws IOException {this(name, name, null, FileCopyUtils.copyToByteArray(contentStream));}/*** Create a new MockMultipartFile with the given content.* @param name the name of the file* @param originalFilename the original filename (as on the client's machine)* @param contentType the content type (if known)* @param content the content of the file*/public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {Assert.hasLength(name, "Name must not be null");this.name = name;this.originalFilename = (originalFilename != null ? originalFilename : "");this.contentType = contentType;this.content = (content != null ? content : new byte[0]);}/*** Create a new MockMultipartFile with the given content.* @param name the name of the file* @param originalFilename the original filename (as on the client's machine)* @param contentType the content type (if known)* @param contentStream the content of the file as stream* @throws IOException if reading from the stream failed*/public MockMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)throws IOException {this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));}@Overridepublic String getName() {return this.name;}@Overridepublic String getOriginalFilename() {return this.originalFilename;}@Override@Nullablepublic String getContentType() {return this.contentType;}@Overridepublic boolean isEmpty() {return (this.content.length == 0);}@Overridepublic long getSize() {return this.content.length;}@Overridepublic byte[] getBytes() {return this.content;}@Overridepublic InputStream getInputStream() {return new ByteArrayInputStream(this.content);}@Overridepublic void transferTo(File dest) throws IOException, IllegalStateException {FileCopyUtils.copy(this.content, dest);}}
效果展示:
图片展示
webp
jpg
大小展示
webp
jpg
压缩了50% 而且还能保质保证图片效果!
本文到此结束啦,希望对你有所帮助!如果害怕下次找不到笔者关注点一点!