当前位置: 首页 > article >正文

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


http://www.kler.cn/a/512700.html

相关文章:

  • STM32之CubeMX图形化工具开发介绍(十七)
  • 迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?
  • 【日志篇】(7.6) ❀ 01. 在macOS下刷新FortiAnalyzer固件 ❀ FortiAnalyzer 日志分析
  • 跨境电商使用云手机用来做什么呢?
  • 和优秀的人一起共事,你会越来越优秀!
  • 使用ffmpeg提高mp4压缩比,减小文件体积【windows+ffmpeg+batch脚本】
  • RM500U-CN模组
  • Vue2+OpenLayers添加缩放、滑块缩放、拾取坐标、鹰眼、全屏控件(提供Gitee源码)
  • 从密码学原理与应用新方向到移动身份认证与实践
  • 【三国游戏——贪心、排序】
  • 国自然面上项目|基于组合机器学习算法的病理性近视眼底多模态影像资料自动化定量分析研究|基金申请·25-01-18
  • 04、Redis从入门到放弃 之 数据持久化RDB和AOF
  • 相机成像及参数原理入门
  • python转转商超书籍信息爬虫
  • B站评论系统的多级存储架构
  • STM32补充——FLASH
  • Qt之文件系统操作和读写
  • 基于海思soc的智能产品开发(视频的后续开发)
  • 什么宠物最好养?
  • PhyCAGE:符合物理规律的图像到 3D 生成
  • 思维的进化:从链式推理到元链式推理的算法探秘
  • go语言两个协程goroutine交替打印1-100
  • 解决用 rm 报bash: /usr/bin/rm: Argument list too long错
  • Javascript 将页面缓存存储到 IndexedDB
  • BH1750使用程序
  • 基于SpringBoot和PostGIS的各国及所属机场信息检索及可视化实现