【Java-图片存储方案】

news2025/1/23 11:03:09

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.coloradmin.cn/o/2280863.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——实验七·排序

嗨~~欢迎来到Tubishu的博客&#x1f338;如果你也是一名在校大学生&#xff0c;正在寻找各种编程资源&#xff0c;那么你就来对地方啦&#x1f31f; Tubishu是一名计算机本科生&#xff0c;会不定期整理和分享学习中的优质资源&#xff0c;希望能为你的编程之路添砖加瓦⭐&…

Windows系统提示RunDLL PcaWallpaperAppDetect错误修复方法

最近&#xff0c;Win11 24H2预览版和Win10 LTSC 2025功能更新偶尔会触发RunDLL错误弹窗 具体表现为 //英文提示 Error in C:\WINDOWS\system32\PcaSvc.dll Missing entry: PcaWallpaperAppDetect//中文提示 C:\WINDOWS\system32\PcaSvc.dll出错 丢失条目:PcaWallpaperAppDe…

计算机组成原理——数据表示(二)

当生活的压力和困惑缠绕在身边&#xff0c;我们往往需要振奋精神&#xff0c;勇往直前。无论在何种困境中&#xff0c;我们都要保持积极的态度和坚定的信念。将悲观的情绪抛之脑后&#xff0c;展现出坚强的意志力和无尽的活力。振奋精神意味着我们要战胜自己内心的负面情绪&…

人源化抗体的改造方式及其优势【卡梅德生物】

随着生物制药行业的迅速发展&#xff0c;抗体药物已经成为治疗多种疾病&#xff08;尤其是癌症、免疫性疾病等&#xff09;的重要手段。抗体人源化改造技术作为抗体药物研发的关键技术之一&#xff0c;在提高药物疗效和降低免疫原性方面发挥了至关重要的作用。 1. 人源化抗体的…

【Linux】深刻理解动静态库

1.什么是库 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个⼈的代码都从零开始&#xff0c;因此库的存在意义⾮同寻常。本质上来说库是⼀种可执⾏代码的⼆进制形式&#xff0c;可以被操作系统载…

【java数据结构】其他非基于比较排序

【java数据结构】其他非基于比较排序 一、计数排序二、基数排序三、桶排序 博客最后附有整篇博客的全部代码&#xff01;&#xff01;&#xff01; 一、计数排序 场景&#xff1a;集中在某个范围内的一组数据 思路&#xff1a; 找到这组序列的最大值和最小值&#xff0c;通过…

博客之星2024年度总评选——我的年度创作回顾与总结

2024年&#xff0c;是我在CSDN博客上持续耕耘、不断成长的一年。在此&#xff0c;与大家分享一下我的年度创作回顾与总结。 一、创作成长与突破 在人工智能领域&#xff0c;技术迭代迅速&#xff0c;知识更新频繁。为了保持自己的竞争力&#xff0c;在今年&#xff0c;我始终…

ChromeOS 132 版本更新

ChromeOS 132 版本更新 1. 企业定制化 Chrome Web Store 管理员现在可以使用新设置定制 Chrome Web Store 以适应他们管理的用户&#xff0c;包括以下功能&#xff1a; 添加公司标志添加首页横幅和自定义公告策划扩展集合实施基于类别的控制 这些设置可以通过管理员控制台进…

Golang Gin系列-5:数据模型和数据库

在这篇Gin教程的博客中&#xff0c;我们将探索如何将模型和数据库与Gin框架无缝集成&#xff0c;使你能够构建健壮且可扩展的web应用程序。通过利用流行的库并遵循最佳实践&#xff0c;你将学习如何定义模型、建立数据库连接、执行CRUD操作以及确保基于gin的项目中的数据完整性…

计算机毕业设计hadoop+spark股票基金推荐系统 股票基金预测系统 股票基金可视化系统 股票基金数据分析 股票基金大数据 股票基金爬虫

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

设计模式的艺术-代理模式

结构性模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解代理模式 代理模式&#xff08;Proxy Pattern&#xff09;&#xff1a;给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用。代理模式是一种对象结构型模式。 代理模式类型较多…

Spring Boot整合Thymeleaf、JDBC Template与MyBatis配置详解

本文将详细介绍如何在Spring Boot项目中整合Thymeleaf模板引擎、JDBC Template和MyBatis&#xff0c;涵盖YAML配置、依赖版本匹配、项目结构设计及代码示例。 一、版本兼容性说明 Spring Boot版本与Java版本对应关系 Spring Boot 2.x&#xff1a;支持Java 8、11&#xff08;推…

【博客之星】2024年度创作成长总结 - 面朝大海 ,春暖花开!

没关系的&#xff0c;大家都会做错选择&#xff0c;会 莫名其妙掉眼泪&#xff0c;走在路上会突然崩溃&#xff0c; 但这并不影响我们去看看晚霞&#xff0c; 再次爱上这个世界。 面朝大海 &#xff0c;春暖花开! about meReviewLife about me 现在我是一名24级计算机类的…

StyleMaster: Stylize Your Video with Artistic Generation and Translation 论文解读

目录 一、概述 二、相关工作 1、图像风格化 2、视频风格化 三、StyleMaster 1、创建对比数据集 2、提取全局描述子 3、局部描述和全局描述结合 4、时间和风格质量的运动适配器 5、Gray Tile ControlNet 四、实验 一、概述 Our StyleMaster demonstrates superior vi…

c++进阶---c++三大特性之一---多态

多态的简单介绍&#xff1a;是一种动态的访问函数&#xff0c;比如&#xff1a;你定义了一个一个人类和一个学生类&#xff0c;当你传入的是学生类的时候&#xff0c;你需要有购物优惠&#xff0c;这种情境下用多态就很适用。 1.简单的多态使用&#xff1a; 1.1构造多态的条件…

安卓程序作为web服务端的技术实现(二):Room 实现数据存储

已经实现web服务器安卓程序作为web服务端的技术实现&#xff1a;AndServer 实现登录权限拦截-CSDN博客 现在需要和正常web项目类似&#xff0c;那么就需要操作数据库 一般web项目都是选择较为重型的数据库如MySQL&#xff0c;SQL server等 这里是安卓项目&#xff0c;我目前…

如何使用Python脚本将本地项目上传到 GitHub

前言 这里我们通过创建一个新的github仓库&#xff0c;来测试我们的脚本能否上传我们本地的项目&#xff0c;并且进行更新。首先你需要先安装 Git&#xff0c;关于这部分我好像没有记录过&#xff0c;这里我搜索看了一下&#xff0c;这篇博客写的Git安装详解应该是比较齐全的&…

Day 15 卡玛笔记

这是基于代码随想录的每日打卡 222. 完全二叉树的节点个数 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#x…

IO进程----进程

进程 什么是进程 进程和程序的区别 概念&#xff1a; 程序&#xff1a;编译好的可执行文件 存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09; 程序是静态的&#xff0c;没有任何执行的概念 进程&#xff1a;一个独立的可调度的任务 执行一个程序分配资…

【Postgres_Python】使用python脚本将多个PG数据库合并为一个PG数据库

需要合并的多个PG数据库表个数和结构一致&#xff0c;这里提供一种思路&#xff0c;选择sql语句insert插入的方式进行&#xff0c;即将其他PG数据库的每个表内容插入到一个PG数据库中完成数据库合并 示例代码说明&#xff1a; 选择一个数据库导出表结构为.sql文件&#xff08…