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

相关推荐
计算机小白一个19 分钟前
蓝桥杯 Java B 组之岛屿数量、二叉树路径和(区分DFS与回溯)
java·数据结构·算法·蓝桥杯
孤雪心殇20 分钟前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
庸俗今天不摸鱼32 分钟前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
菠菠萝宝33 分钟前
【Java八股文】10-数据结构与算法面试篇
java·开发语言·面试·红黑树·跳表·排序·lru
奔跑吧邓邓子36 分钟前
【Python爬虫(36)】深挖多进程爬虫性能优化:从通信到负载均衡
开发语言·爬虫·python·性能优化·负载均衡·多进程
不会Hello World的小苗40 分钟前
Java——链表(LinkedList)
java·开发语言·链表
lsx2024061 小时前
Perl 面向对象编程指南
开发语言
Allen Bright1 小时前
【Java基础-46.3】Java泛型通配符详解:解锁类型安全的灵活编程
java·开发语言
柃歌1 小时前
【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
java·数据结构·笔记·学习·算法
柃歌1 小时前
【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记
java·数据结构·笔记·学习·算法