【图片存储】利用java web将图片以二进制和Base64编码存入数据库中,并从数据库中获取到数据进行解码展示为图片


一、问题描述

  • 将用户在网页上上传的图片进行编码后,分别以二进制和base64格式存入数据库
  • 将数据库中查询到的信息解码后显示在页面中

二、问题解决

说明:

本篇文章使用的技术栈为 spring boot + mybatis-plus +thymeleaf


1. 前后端和数据库代码

前端上传页面

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
	</head>
	<body>
		<div class="ibox-content">
			<form th:action="@{/add_picture_post}" enctype="multipart/form-data" method="post">
				<label class="font-bold">选择二进制存储文件</label>
				<input type="file" class="form-control" name="binPto" style="width: 285px;margin: 0 auto"> <br/>
				<label class="font-bold">选择base64存储文件</label>
				<input type="file" class="form-control" name="base64Pto" style="width: 285px;margin: 0 auto"><br/>
				<button class="btn btn-primary" type="submit">
					<strong>提交</strong>
				</button>
			</form>
		</div>
	</body>
</html>

前端展示页面

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
	</head>
	<body class="gray-bg">
		<table class="table table-striped table-bordered table-hover dataTables-example">
			<thead>
				<tr>
					<th>序号</th>
					<th>出生日期</th>
					<th>二进制图片</th>
					<th>base64编码图片</th>
				</tr>
			</thead>
			<tbody>
				<tr th:each="largeText,stats:${largeTextList}">
					<td th:text="${stats.count}"></td>
					<td th:text="${largeText.birth}"></td>
					<td><img th:src="@{/get_bin_pto(id=${largeText.id})}"></td>
					<td><img th:src="@{/get_base64_pto(id=${largeText.id})}"></td>
				</tr>
			</tbody>
			<tfoot>
				<tr>
					<th>序号</th>
					<th>出生日期</th>
					<th>二进制图片</th>
					<th>base64编码图片</th>
				</tr>
			</tfoot>
		</table>
	</body>
</html>

实体类

package priv.happy.hospitaldrugmanagementsystem.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.OutputStream;
import java.io.Serializable;

/**
 * @Author: HAPPY 
 * @Project_name: project
 * @Package_name: priv.happy.domain
 * @Date: 2021/11/11 10:28
 * @Description:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "hospital_drug_management_system.large_text")
public class LargeText implements Serializable {
    @TableId(value = "id", type = IdType.INPUT)
    private Integer id;

    @TableField(value = "binary_photo")
    private byte[] binaryPhoto;

    @TableField(value = "base64_photo")
    private String base64Photo;

    private static final long serialVersionUID = 1L;
}

controller代码

@Controller
public class LargeTextController {
    @Autowired
    LargeTextService largeTextService;
    
    /**
     * 向数据库中添加大文本数据
     * @param largeText 获取基础属性,姓名、出生日期
     * @param binPho 以二进制存储的图像
     * @param base64Pto 以base64编码存储的图像
     * @return 要跳转到的目标请求
     */
	@PostMapping("/add_picture_post")
    public String savePic(LargeText largeText, @RequestParam("binPto") MultipartFile binPho, @RequestParam("base64Pto") MultipartFile base64Pto) {
        // 利用工具类转为二进制编码
        largeText.setBinaryPhoto(ImageUtil.getBinary(binPho));

        // 利用工具类转为base64编码
        largeText.setBase64Photo(ImageUtil.generateBase64(base64Pto));
        largeTextService.save(largeText);
        return "redirect:view_all_picture_get";
    }
	
	/**
     * 响应ajax请求,根据编号获取图片的二进制解码流
     *
     * @param id 图片id
     * @return 二进制编码数组
     */
	@GetMapping(value = "/get_bin_pto", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getBinPto(Integer id) {
        return largeTextService.getById(id).getBinaryPhoto();
    }
	
	
    /**
     * 响应ajax请求,根据编号获取图片的base64解码后的流
     *
     * @param id 图片id
     * @return 二进制编码数组
     */
    @GetMapping(value = "/get_base64_pto", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getBase64Pto(Integer id) {
        LargeText largeText = largeTextService.getById(id);
        return ImageUtil.decodeBase64Str(largeText.getBase64Photo());
    }
    
    // 查询所有数据
	@GetMapping("/view_all_picture_get")
    public String viewAllPictureGet(Model model) {
        List<LargeText> largeTextList = largeTextService.list();
        model.addAttribute("largeTextList", largeTextList);
        return "largetext/view_all_picture";
    }
}

service和mapper都是采用的继承字mybatis-plus的接口直接实现的,没有自己的代码,这里就不写了

工具类

package priv.happy.hospitaldrugmanagementsystem.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Base64;
import java.util.List;

/**
 * @Author: HAPPY
 * @Project_name: project
 * @Package_name: priv.happy.hospitaldrugmanagementsystem.util
 * @Date: 2021/11/14 10:34
 * @Description:此工具类用于将文件转为二进制和Base64格式的编码以及解码 base64格式可以起到图像压缩的作用
 * 二进制格式不能起到压缩作用
 */
public class ImageUtil {
    static BASE64Encoder miscEncoder = new sun.misc.BASE64Encoder();
    static BASE64Decoder miscDecoder = new sun.misc.BASE64Decoder();
    static Base64.Encoder utilEncoder = Base64.getEncoder();
    static Base64.Decoder utilDecoder = Base64.getDecoder();

    /**
     * 将图片文件编码为base64格式字符串
     *
     * @param file 图片文件的路径
     * @return 返回编码后的字符串
     */
    public static String getImageBase64(File file) {
        BufferedImage bi;
        ByteArrayOutputStream baos = null;
        try {
            bi = ImageIO.read(file);
            baos = new ByteArrayOutputStream();
            List<String> split = StrUtil.split(file.getName(), ".");

            // 自动截取文件扩展名
            String formatName = split.get(split.size() - 1);

            ImageIO.write(bi, formatName, baos); // jpg
            byte[] bytes = baos.toByteArray();
            return miscEncoder.encodeBuffer(bytes).trim();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 将base64格式的编码解码为图片文件并在指定路径下生成图片
     *
     * @param base64String 要解码的字符串
     * @param path         生成图片的路径,可以是jpg、png、gif格式
     * @return 返回成功与否
     */
    public static boolean base64StringToImage(String base64String, String path) {
        BufferedImage bi1;
        ByteArrayInputStream bais = null;
        try {
            byte[] bytes1 = miscDecoder.decodeBuffer(base64String);

            bais = new ByteArrayInputStream(bytes1);

            bi1 = ImageIO.read(bais);
            File w2 = new File(path);//
            if (!w2.exists()) {
                // 如果文件不存在,则创建新文件
                w2.createNewFile();
            }
            ImageIO.write(bi1, "jpg", w2);  // 不管输出什么格式图片,此处不需改动
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将springboot前端上传的文件编码为base64格式字符串
     *
     * @param file 上传的文件
     * @return 编码后的字符串
     */
    public static String generateBase64(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return "图片不能为空!";
        }
        byte[] imageBytes = null;
        String base64EncoderImg = "";
        try {
            imageBytes = file.getBytes();
            base64EncoderImg = utilEncoder.encodeToString(imageBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return base64EncoderImg;
    }

    /**
     * 将base64字符串解码为二进制流
     *
     * @param base64String 要解码的字符串
     * @return 返回解码后的
     */
    public static byte[] decodeBase64Str(String base64String) {
        return utilDecoder.decode(base64String);
    }

 	/**
     * 将spring boot上传的文件编码为二进制流
     * @param file 要编码的文件
     * @return 返回文件二进制数组
     */
    public static byte[] getBinary(MultipartFile file) {
        try {
            return file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

数据库

create table hospital_drug_management_system.large_text
(
    id           int auto_increment
        primary key,
    binary_photo longblob    null,
    base64_photo longtext    null
);

2.效果图

说明:

  • 为了简化起见,本文中我删除了姓名和出生日期

页面
在这里插入图片描述
数据库在这里插入图片描述


三、说明

1、 关于工具类

工具类使用了两种Base64的编码和解码方式:

第一种,使用旧版方式

sun.misc.BASE64Decoder;
sun.misc.BASE64Encoder;

第二种,使用新版方式

java.util.Base64;

2、两种编码方式区别:

第一种方式编码和解码处理效率较差,实际测试编码与解码速度,Java 8提供的Base64,要比sun.misc套件提供的快至少11倍!

具体可以参考Java如何进行Base64的编码(Encode)与解码(Decode)?

  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
JavaWeb 连接数据库,一般需要使用 JDBC 技术。下面是连接 MySQL 数据库的示例代码: 1. 导入 JDBC 驱动包 在项目添加 JDBC 驱动包,例如 MySQL 的驱动包:mysql-connector-java-x.x.xx.jar。 2. 加载 JDBC 驱动 使用 Class.forName() 方法加载 JDBC 驱动,例如 MySQL 的驱动类为 com.mysql.jdbc.Driver: ``` Class.forName("com.mysql.jdbc.Driver"); ``` 3. 设置数据库连接信息 设置数据库连接的 URL、用户名和密码: ``` String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; ``` 其,url 表示数据库的地址和端口号,test 表示数据库的名称。 4. 建立数据库连接 使用 DriverManager.getConnection() 方法建立数据库连接: ``` Connection conn = DriverManager.getConnection(url, user, password); ``` 5. 操作数据库 使用 Connection 对象进行数据库操作,例如创建 Statement 对象并执行 SQL 语句: ``` Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM user"); while (rs.next()) { System.out.println(rs.getString("name")); } ``` 完整代码示例: ``` import java.sql.*; public class Test { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM user"); while (rs.next()) { System.out.println(rs.getString("name")); } rs.close(); stmt.close(); conn.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } ``` 这是一个简单的连接 MySQL 数据库的示例,你可以根据需要修改数据库连接信息和 SQL 语句。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别来BUG求求了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值