什么是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 somewhere
            BufferedImage image = ImageIO.read(file);
            // Obtain a WebP ImageWriter instance
            ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
            // Configure encoding parameters
            WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
            writeParam.setCompressionMode(WebPWriteParam.MODE_DEFAULT);
            // Configure the output on the ImageWriter
            writer.setOutput(new FileImageOutputStream(new File(outputWebpPath)));
            // Encode
            writer.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;
	@Nullable
	private 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));
	}
	@Override
	public String getName() {
		return this.name;
	}
	@Override
	public String getOriginalFilename() {
		return this.originalFilename;
	}
	@Override
	@Nullable
	public String getContentType() {
		return this.contentType;
	}
	@Override
	public boolean isEmpty() {
		return (this.content.length == 0);
	}
	@Override
	public long getSize() {
		return this.content.length;
	}
	@Override
	public byte[] getBytes() {
		return this.content;
	}
	@Override
	public InputStream getInputStream() {
		return new ByteArrayInputStream(this.content);
	}
	@Override
	public void transferTo(File dest) throws IOException, IllegalStateException {
		FileCopyUtils.copy(this.content, dest);
	}
}
效果展示:
图片展示
webp

jpg

大小展示
webp

jpg

压缩了50% 而且还能保质保证图片效果!
本文到此结束啦,希望对你有所帮助!如果害怕下次找不到笔者关注点一点!




![[C++] const 成员函数](https://img-blog.csdnimg.cn/direct/884b272cec4f4d5294564e1403901c3b.png)














