【Java-图片存储方案】

Java功能相关文章

一、Minio存储大体量图片

  • 上传到Minio指定路径,前端预览时,需要生成临时访问凭证的URL
java 复制代码
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类型字段中。后端代码:
java 复制代码
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!";
        }
    }
}
  • 前端代码
java 复制代码
<!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 等),避免将图片数据直接存储在数据库中,导致性能问题。

相关推荐
skywalk816319 分钟前
言知项目后续方向建议
开发语言·学习·编程
阿狸猿34 分钟前
论微服务架构及其应用
java·微服务·架构
拉勾科研工作室1 小时前
区块链工程毕业论文题目【249个】
开发语言·javascript
程序员黑豆1 小时前
Java中的字符串【AI全栈开发】
java
namexingyun1 小时前
开源前端生态如何成为 AI UI 生成的“燃料“:shadcn/ui、Tailwind CSS、Storybook 技术价值全解剖
java·前端·人工智能·python·ui·开源·ai编程
z落落1 小时前
C#WinForm控件实战:Panel与单选框动态创建
开发语言·c#
ptc学习者1 小时前
python 中描述符@property property 大概的样子
开发语言·python
zmzb01032 小时前
Python课后习题训练记录Day129
开发语言·python
终将老去的穷苦程序员2 小时前
基于SpringBoot的餐饮管理系统
java·spring boot·后端
心之伊始2 小时前
Spring AI Tool Calling 实战:让 Java Agent 调用本地 Bean 工具方法
java·spring boot·agent·spring ai·tool calling