想必你碰到这些情况:

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   不爱美女爱辣条  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?



点击右上角即可分享
微信分享提示