利用图片与Base64互转,实现图片的上传下载


前言

  1. 后端在没有文件服务器的情况下,图片可通过Base64编码的格式进行上传下载。
  2. Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是 一种基于64个可打印字符来表示二进制数据的方法。
  3. Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

1、方式一:前端进行Base64转码

提示:前端进行文件图片的转码可减小后端处理的压力,推荐此方式。

1.1、使用步骤

1.1.1.前端HTML代码

代码如下(示例):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传图片</title>
</head>
<body>
<form action="xxxx" method="post" enctype="multipart/form-data">
    <input type="file" name="upload" id="upImageFile" onchange="function ImageToBase64() {
             let files = document.getElementById('upImageFile').files[0];
                const reader = new FileReader();
                reader.readAsDataURL(files)
                reader.onload = () => {
                    console.log('base结果:' + reader.result)
                }
    }
    ImageToBase64()"/>
    </form>
</body>
<script>
</script>
</html>

2.2.2.前端console日志

在这里插入图片描述

前端进行图片的Base64转码,传入后端,后端用String接收 入库即可。


2、方式二:后端进行Base64转码(前端上传文件)

提示:mysql存储二进制图片类型为mediumblob(最大可存储16M)。
	对应Java实体类型为byte[]

2.1、库表

2.1.1、建表语句

CREATE TABLE `test_icon` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `icon` mediumblob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='测试图片存储'

2.1.2、ER图

在这里插入图片描述

2.2、后端代码

2.2.1、实体类

package com.erba.entity;

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 java.io.Serializable;

@TableName("test_icon")
public class Icon implements Serializable {

    @TableId(value = "id",type = IdType.AUTO)
    private Long id;

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public byte[] getIcon() {
        return icon;
    }

    public void setIcon(byte[] icon) {
        this.icon = icon;
    }

    public Icon(byte[] icon) {
        this.icon = icon;
    }
}

2.2.2、controller

package com.erba.controller;

import com.erba.entity.Icon;
import com.erba.service.IconService;
import com.erba.util.Base64Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Controller
@ResponseBody
@RequestMapping("/hello")
public class HelloController {

    @Autowired
    private IconService iconService;

    @RequestMapping("/test")
    @CrossOrigin
    public List<Icon> test() {
        List<Icon> list = iconService.list();
        String s = Base64Util.byteToBase64(list.get(0).getIcon());
        System.out.println(s);
        return list;

    }

    @PostMapping("/upload")
    public void uploadFile(MultipartFile file) throws IOException {
        String fileName = file.getName();
        System.out.println("文件名:" + fileName);
        String s = Base64Util.fileToBase64Str(file);
        byte[] arr = file.getBytes();
        System.out.println(Arrays.toString(arr));
        System.out.println("base64:" + s);
        iconService.save(new Icon(arr));
    }
}

2.2.3、Base64工具类(需自取)

package com.erba.util;



import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;


import java.io.*;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

/**
 * @author xxx
 * @description Base64工具类
 **/
public class Base64Util {

    /**
     * @Description: base64转文件
     * @Param: [file64Str, outPath]
     * @Return: boolean
     **/
    public static boolean base64StrToFile(String file64Str, String outPath) {
        if (file64Str == null)
            return false;
        Decoder decoder = Base64.getDecoder();
        try {
            // 解密
            byte[] b = decoder.decode(file64Str);
            // 处理数据
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            // 文件夹不存在则自动创建
            File tempFile = new File(outPath);
            if (!tempFile.getParentFile().exists()) {
                tempFile.getParentFile().mkdirs();
            }
            OutputStream out = new FileOutputStream(tempFile);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @Description: base64转MultipartFile
     * @Param: [base64Str]
     * @Return: org.springframework.web.multipart.MultipartFile
     **/
    public static MultipartFile base64StrToMultipartFile(String base64Str){
        if (StringUtils.isEmpty(base64Str)){
            return null;
        }
        Decoder decoder = Base64.getDecoder();
        MultipartFile multipartFile = null;
        try {
            // 解密
            byte[] b = decoder.decode(base64Str);
            multipartFile = new MockMultipartFile("file.png", b);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return multipartFile;
    }

    /**
     * @Description: 文件转base64(路径入参)
     * @Param: [filePath]
     * @Return: java.lang.String
     **/
    public static String fileToBase64Str(String filePath) {
        InputStream inputStream;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(filePath);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(data);
    }

    /**
     * @Description: 文件转base64(文件入参)
     * @Param: [file]
     * @Return: java.lang.String
     **/
    public static String fileToBase64Str(MultipartFile file) {
        InputStream inputStream;
        byte[] data = null;
        try {
            inputStream = file.getInputStream();
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(data);
    }

    /**
     * @Description: byte转Base64
     * @Param: [data]
     * @Return: java.lang.String
     **/
    public static String byteToBase64(byte[] data){
        // 加密
        Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(data);
    }

}

2.2.4、Http测试(http文件)

POST http://localhost:8080/hello/upload
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="111.png"

< C:\Users\hzf\Desktop\111.png
--WebAppBoundary--

###

###
GET http://localhost:8080/hello/test
Accept: application/json

###

2.2.5、控制台输出

在这里插入图片描述

2.2.6、数据库

在这里插入图片描述

总结

在MySQL中Blob是一个二进制的对象,它是一个可以存储大量数据的容器(如图片,音乐等等),且能容纳不同大小的数据,在MySQL中有四种Blob类型,他们的区别就是可以容纳的信息量不容分别是以下四种:
  ①TinyBlob类型  最大能容纳255B的数据
  ②Blob类型  最大能容纳65KB的
  ③MediumBlob类型  最大能容纳16MB的数据
  ④LongBlob类型  最大能容纳4GB的数据
  而在我们实际使用的时候,可以根据自己的需求选择这几种类型,但是如果Blob中存储的文件的大小过大的话,会导致数据库的性能很差。
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值