【Java-图片存储方案】
Java功能相关文章
一、Minio存储大体量图片
- 上传到Minio指定路径,前端预览时,需要生成临时访问凭证的URL
import io.minio.MinioClient;
import io.minio.errors.MinioException;
import io.minio.http.Method;
import io.minio.GetPresignedObjectUrlArgs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.io.IOException;
import java.time.Duration;
@Service
public class MinioService {
private final MinioClient minioClient;
private final String bucketName;
//minio.endpoint=http://localhost:9000
//minio.access-key=your-access-key
//minio.secret-key=your-secret-key
//minio.bucket-name=your-bucket-name
public MinioService(@Value("${minio.endpoint}") String endpoint,
@Value("${minio.access-key}") String accessKey,
@Value("${minio.secret-key}") String secretKey,
@Value("${minio.bucket-name}") String bucketName) throws MinioException {
this.bucketName = bucketName;
this.minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
public String uploadFile(MultipartFile file, String path) throws MinioException, IOException {
// 上传文件到Minio
try (InputStream inputStream = file.getInputStream()) {
minioClient.putObject(bucketName, path, inputStream, file.getContentType());
}
// 返回文件的访问路径
return getFileUrl(path);
}
public String getFileUrl(String path) {
try {
// 使用 GetPresignedObjectUrlArgs 创建预签名 URL
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.method(Method.GET) // 获取文件的 URL
.bucket(bucketName)
.object(path)
.expires(Duration.ofHours(1)) // 设置有效期,这里是1小时
.build();
// 获取预签名的文件 URL
return minioClient.getPresignedObjectUrl(args);
} catch (MinioException e) {
e.printStackTrace();
return null;
}
}
}
二、小图片Mysql存储
- 小体积图片存储,使用Base64将图片转换为字符串,存储到Mysql的Text类型字段中。后端代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Base64;
@RestController
@RequestMapping("/image")
public class ImageController {
@Autowired
private ImageDataRepository imageDataRepository;
// 上传图片并转换为Base64
@PostMapping("/upload")
public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
// 将上传的图片转换为字节数组
byte[] imageBytes = file.getBytes();
// 获取文件类型(例如 "image/jpeg")
String mimeType = file.getContentType(); // 获取上传的图片类型,例如 image/jpeg
// 将字节数组转换为 Base64 字符串
String base64Image = Base64.getEncoder().encodeToString(imageBytes);
// 拼接前缀(例如 "data:image/jpeg;base64,")
String base64WithPrefix = "data:" + mimeType + ";base64," + base64Image;
// 将 Base64 字符串存储到数据库
ImageData imageData = new ImageData();
imageData.setImageBase64(base64WithPrefix);
imageDataRepository.save(imageData);
return "Image uploaded successfully!";
}
// 获取图片并返回完整的 Base64 字符串
@GetMapping("/get/{id}")
public String getImage(@PathVariable Integer id) {
// 从数据库获取图片数据
ImageData imageData = imageDataRepository.findById(id).orElse(null);
if (imageData != null) {
return imageData.getImageBase64(); // 直接返回完整的 Base64 字符串(带前缀)
} else {
return "Image not found!";
}
}
}
- 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload and Display</title>
</head>
<body>
<h1>Upload and Display Image</h1>
<!-- 图片上传表单 -->
<form id="imageUploadForm">
<input type="file" id="imageFile" name="file" accept="image/*" required />
<button type="submit">Upload Image</button>
</form>
<h2>Uploaded Image:</h2>
<img id="uploadedImage" alt="Uploaded Image" width="300" />
<script>
// 监听上传表单提交
document.getElementById('imageUploadForm').addEventListener('submit', function(event) {
event.preventDefault();
const formData = new FormData();
const fileInput = document.getElementById('imageFile');
formData.append('file', fileInput.files[0]);
// 发送文件到后端
fetch('/image/upload', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(result => {
alert(result); // 显示上传成功信息
})
.catch(error => {
console.error('Error:', error);
});
});
// 根据 ID 获取图片并显示
function fetchImage(imageId) {
fetch(`/image/get/${imageId}`)
.then(response => response.text())
.then(base64Image => {
// 将返回的完整 Base64 字符串设置为 img 标签的 src 属性
document.getElementById('uploadedImage').src = base64Image;
})
.catch(error => {
console.error('Error:', error);
});
}
// 假设上传成功后返回的图片 ID 是 1
// 你可以用以下代码来调用并展示图片
// fetchImage(1);
</script>
</body>
</html>
-
后端:
上传图片时,通过 file.getContentType() 获取文件的 MIME 类型(如 image/jpeg)。
将 Base64 编码的字符串与 MIME 类型拼接,形成完整的 Base64 格式(data:image/jpeg;base64,…)。
将这个完整的 Base64 字符串存储到数据库。
在获取图片时,直接返回这个完整的 Base64 字符串。 -
前端:
通过 fetch 请求从后端获取完整的 Base64 字符串(包括 data:image/jpeg;base64,… 前缀)。
将这个字符串设置为 img 标签的 src 属性,从而在网页中显示图片。
总结
Base64这种方式适合存储较小的图片,适用于头像等小图。对于较大的图片文件,存储图片的 URL 或使用外部存储服务(如 AWS S3、阿里云 OSS 等),避免将图片数据直接存储在数据库中,导致性能问题。
原文地址:https://blog.csdn.net/qq_40570699/article/details/145264081
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!