【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 等),避免将图片数据直接存储在数据库中,导致性能问题。

相关推荐
RainbowSea12 小时前
11. LangChain4j + Tools(Function Calling)的使用详细说明
java·langchain·ai编程
考虑考虑16 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613516 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊17 小时前
Java学习第22天 - 云原生与容器化
java
渣哥19 小时前
原来 Java 里线程安全集合有这么多种
java
间彧19 小时前
Spring Boot集成Spring Security完整指南
java
间彧20 小时前
Spring Secutiy基本原理及工作流程
java
Java水解21 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆1 天前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学1 天前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端