最近项目有个需求需要在前端vue上传图片,然后在后端将图片存到本地的一个文件夹下。

1、vue

这里是将上传图片封装成了一个组件来使用,组件名为 upload-image.vue

<template>
  <div class="clearfix">
    <!--
        name    —— 向后端传递数据时会要用到
        action  —— 后端路径
    -->
    <a-upload
        name="faceImage"            
        :headers="headers"
        :action="fileurl"
        list-type="picture-card"
        v-model:file-list="fileList"
        :before-upload="beforeUpload"
        @preview="handlePreview"
        @change="handleChange"
    >
      <div v-if="fileList.length < imgNum">
        <a-icon type="plus" />
        <div class="ant-upload-text">
          上传图片
        </div>
      </div>
    </a-upload>
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>

<script>
import mitt from "@/utils/mitt";

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

export default {
  name: "uoload-image",
  data(){
    return{
      imgNum:1,              //设置最多可以上传的图片数量
      headers: {    
        'token': localStorage.getItem('token'),
      },
      fileurl:"/api/file/upload",       //上传到后端的路径
      previewVisible: false,
      previewImage: '',
      fileList: []
    }
  },
  methods:{
    handleCancel() {
      this.previewVisible = false;
    },
    async handlePreview(file) {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj);
      }
      this.previewImage = file.url || file.preview;
      this.previewVisible = true;
    },
    // 检查图片格式和图片大小
    beforeUpload(file){
      //图片格式限制为 jpeg、png
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === "image/png";
      if (!isJpgOrPng){
        this.$message.error("请选择jpg/png图片");
      }
       
      //图片大小限制为 2M以内
      const isLt2M = file.size/1024/1024 <= 2;
      if (!isLt2M){
        this.$message.error("图片大小不能超过2MB,请重新上传");
      }
      return isJpgOrPng && isLt2M;
    },
    handleChange ({ file, fileList }) {
      this.fileList = fileList;
      if (file.hasOwnProperty('error')){
        this.$message.error("图片上传失败");
        return;
      }
    },
  }
}
</script>

<style scoped>
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>

注意:后端路径有个地方需要注意,关于这里的 ' /api ',我在vue.config.js做了跨域处理

2、后端springboot

@RestController
@RequestMapping("/file")
public class UploadImageController {
    //这里的 faceImage 就是 a-upload 的 name 属性
    @PostMapping("/upload")
    public void uploadImage(@RequestParam("faceImage") MultipartFile pic) {
        /*
         * 编码为字符串
         */
        String base64Str = "";
        try {
            base64Str = Base64Utils.encodeToString(pic.getBytes());     //将图片转化为base64格式
            String imgName = pic.pic.getOriginalFilename();             //获取到图片原本的名字
            storeImageAtLocal(base64Str, imgName);                      //为了方便在其他地方调用,这里封装成了一个工具类
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
public class UploadUtil {
    //这里的pathName表示 你要存到哪,图片名叫啥,如D:\\resources\\image\\smile.jpg

    public static void storeImageAtLocal(String base64ImgData,String pathName){
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] bytes = decoder.decode(base64ImgData);
        /*
         * 字节流转文件
         */
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(pathName);
            fos.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //本地图片转base64编码数据
    public static String getImageBase64Data(String localPath){
        File file = new File(localPath);    //URL url = new URL(src);
        byte[] data = null;
        try {
            InputStream in = new FileInputStream(file);  //InputStream in = url.openStream();
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(data);
    }

}
Logo

前往低代码交流专区

更多推荐