想必你碰到这些情况:

image

哈哈大部分我们都会去干嘛呢?

image

作为计算机学者啊 肯定会想到一些这些坑爹收费的垃圾东西 我们自己搞搞
其实这不就是我们经常写过的文件上传下载业务吗
参考:https://www.cnblogs.com/gaodiyuanjin/p/18410900
结合博客园博主与统义灵码结合

图片插件依赖
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.20</version>
        </dependency>
前页面显示:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片上传和下载</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f4f4f9;
        }
        .container {
            text-align: center;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        button {
            margin: 10px;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>图片上传和下载</h1>
        <button id="uploadButton">上传图片</button>
        <button id="downloadButton">下载图片</button>
        <input type="file" id="fileInput" style="display:none;" accept="image/*">
        <img id="previewImage" src="" alt="预览图片" style="display:none; max-width: 300px; margin-top: 20px;">
    </div>

    <script>
        document.getElementById('uploadButton').addEventListener('click', function() {
            document.getElementById('fileInput').click();
        });

        document.getElementById('fileInput').addEventListener('change', function(event) {
            const file = event.target.files[0];
            if (file) {
                const formData = new FormData();
                formData.append('file', file);

                fetch('/api/images/upload', {
                    method: 'POST',
                    body: formData
                })
                .then(response => response.text())
                .then(message => {
                    alert(message);
                    if (message === "图片上传成功") {
                        const reader = new FileReader();
                        reader.onload = function(e) {
                            const img = document.getElementById('previewImage');
                            img.src = e.target.result;
                            img.style.display = 'block';
                        };
                        reader.readAsDataURL(file);
                    }
                })
                .catch(error => console.error('Error:', error));
            }
        });

        document.getElementById('downloadButton').addEventListener('click', function() {
            const img = document.getElementById('previewImage');
            if (img.src) {
                const filename = img.src.split('/').pop();
                window.location.href = `/api/images/download/${filename}`;
            } else {
                alert('请先上传图片');
            }
        });
    </script>
</body>
</html>

业务controller
package com.example.demo;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

@RestController
@RequestMapping("/api/images")
public class ImageController {
    private static final String UPLOAD_DIR = "D:/zhaowenya/";
    private static final int MAX_WIDTH = 380; // 最大宽度
    private static final int MAX_HEIGHT = 640; // 最大高度

    @PostMapping("/upload")
    public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return ResponseEntity.badRequest().body("请选择一个文件");
            }

            // 检查文件类型
            if (!file.getContentType().startsWith("image")) {
                return ResponseEntity.badRequest().body("文件类型不支持");
            }

            // 读取图片
            BufferedImage originalImage = ImageIO.read(file.getInputStream());

            // 调整图片大小
            BufferedImage resizedImage = Thumbnails.of(originalImage)
                    .size(MAX_WIDTH, MAX_HEIGHT)
                    .keepAspectRatio(false) // 不保持宽高比
                    .outputFormat("jpg") // 指定输出格式
                    .asBufferedImage();

            // 压缩图片到指定大小
            File destFile = new File(UPLOAD_DIR, file.getOriginalFilename());
            compressImageToSize(resizedImage, destFile, 20 * 1024); // 20 KB

            return ResponseEntity.ok("图片上传成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("上传失败");
        }
    }

    @GetMapping("/download/{filename}")
    public ResponseEntity<Resource> downloadImage(@PathVariable String filename) {
        try {
            File file = new File(UPLOAD_DIR + filename);
            if (!file.exists()) {
                return ResponseEntity.notFound().build();
            }

            Resource resource = new FileSystemResource(file);

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                    .contentType(MediaType.IMAGE_JPEG) // 根据实际情况调整媒体类型
                    .body(resource);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }

    private void compressImageToSize(BufferedImage image, File destFile, int targetSizeInBytes) throws IOException {
        float quality = 1.0f; // 初始质量
        float minQuality = 0.1f; // 最小质量
        float maxQuality = 1.0f; // 最大质量

        byte[] compressedImageBytes;
        do {
            compressedImageBytes = compressImage(image, quality);
            quality -= 0.1f; // 减少质量以减小文件大小
        } while (compressedImageBytes.length > targetSizeInBytes && quality >= minQuality);

        if (compressedImageBytes.length > targetSizeInBytes) {
            throw new IOException("无法将图片压缩到指定大小");
        }

        try (FileOutputStream fos = new FileOutputStream(destFile)) {
            fos.write(compressedImageBytes);
        }
    }

    private byte[] compressImage(BufferedImage image, float quality) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
        if (!writers.hasNext()) {
            throw new IOException("不支持的图片格式");
        }
        ImageWriter writer = writers.next();
        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(quality);

        try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
            writer.setOutput(ios);
            writer.write(null, new IIOImage(image, null, null), param);
        } finally {
            writer.dispose();
        }

        return baos.toByteArray();
    }
}

通过上述你可以自定义去修改一些什么kb 宽高 保存位置 图片格式啊什么的
其实这些业务从来都是“大自然的搬运工” 只不过需要的是你持续不断愿意学习能力

posted on 2024-12-05 10:25  蒸饺  阅读(22)  评论(0)    收藏  举报