js 上传图片文件,限制格式、大小和尺寸

发布时间 2023-12-23 17:17:25作者: front-gl

通过js限制上传图片

前言

做前端项目时,经常会用到form表单,偶尔也会用到input标签来提交上传图片文件。在上传文件时,有时候会有一定的条件,比如图片格式、大小及尺寸。

通过js,可以在前端来设置上传图片的格式、尺寸及大小,并验证。

主要方法

1、设置上传图片的格式

jsp代码,设置form表单的input标签

<input type="file" id="file" name="file" onchange="verificationPicFile(this);verificationPicFile1(this)" >
onchange属性:在域的内容改变时发生。
js代码,设置图片的格式
//验证上传文件的格式
function verificationPicFile(file) {
    var fileTypes = [".jpg", ".png", ".jpeg", ".PNG", ".gif"];//文件后缀只能是这五类
    var filePath = document.getElementById("file").value;//返回的是上传文件的路径名 例如:E:\xx\xxx.jpg
    //当括号里面的值为0、空字符、false 、null 、undefined的时候就相当于false
    if(filePath){
        var isNext = false;
        var fileEnd = filePath.substring(filePath.indexOf("."));//截取文件名的后缀
        for (var i = 0; i < fileTypes.length; i++) {
            if (fileTypes[i] == fileEnd) {
                isNext = true;
                break;
            }
        }
        if (!isNext){
            alert('不接受此文件类型');
            document.getElementById("file").value = "";//如果文件后缀名不符合,清空已选择文件
            return false;
        }
    }else {
        return false;
    }
}
2、设置上传图片的大小
//图片大小验证
function verificationPicFile(file) {
    var fileSize = 0;
    var fileMaxSize = 1024;//1M
    var filePath = file.value;
    if(filePath){
        fileSize =file.files[0].size;
        var size = fileSize / 1024;
        if (size > fileMaxSize) {
            alert("文件大小不能大于1M!");
            file.value = "";
            return false;
        }else if (size <= 0) {
            alert("文件大小不能为0M!");
            file.value = "";
            return false;
        }
    }else{
        return false;
    }
}
3、设置上传图片的尺寸
//图片尺寸验证
function verificationPicFile1(file) {
    var filePath = document.getElementById("file");
    /*alert(filePath.files) 返回Object FileList*/
    if(filePath.files){
        //读取图片数据
        var f = filePath.files[0];//返回Object File
        var reader = new FileReader();  //通过FileReader类型读取文件中的数据(异步文件读取)
        reader.onload = function (e) {  
            var data = e.target.result;  //返回文件框内上传的对象
            //加载图片获取图片真实宽度和高度  
            var image = new Image();  
            image.onload = function(){  
                var width = image.width;
                var height = image.height;  
                alert('文件像素宽:' + width +',文件像素高:'+ height + '文件大小:'+f.size + '字节');
                if (width == 295 & height == 413){
                    alert("文件尺寸符合!");
                }else {
                    alert("文件尺寸应为:295*413(像素)!");
                    document.getElementById("file").value = "";
                    return false;
                }
            };  
            image.src= data;  //img.src 应该是放在 onload 方法后边的, 因为当image的src发生改变,浏览器就会跑去加载这个src里的资源,先告诉浏览器图片加载完要怎么处理,再让它去加载图片
        };  
       
        reader.readAsDataURL(f);//读取文件并将文件数据以URL形式保存到result属性中。 读取图像常用
    }else{
        return false;
    }
}

 

 

亲测有效:

// 原生JS onload 是异步函数,上传图片接口必须写在里面,不能放外面
const fileNameChanged = function() {
    var files = document.querySelector('input[type="file"]').files;
    console.log('files', files[0])
    const file = files[0]
    // 控制大小,这里根据需要自行设置
    if (file.size > 1024*1024*5) {
      toastr.warning("限制5M内图片上传")
      return
    }
    // 控制尺寸
    let widthPix = $scope.deviceInfo.inScreen.width
    let heightPix = $scope.deviceInfo.inScreen.height
    console.log('背景图片像素', widthPix, heightPix)
    
    var reader = new FileReader();  //通过FileReader类型读取文件中的数据(异步文件读取)
    reader.onload = function (e) {  
        var data = e.target.result;  //返回文件框内上传的对象
        //加载图片获取图片真实宽度和高度  
        var image = new Image();  
        image.onload = function(){  
            var width = image.width;
            var height = image.height; 
            if (width == widthPix && height == heightPix){ // 尺寸正确,执行下面的函数
                console.log('参数', $rootScope.equipmentId, $rootScope.projectCode)
                var form = new FormData();
                form.append('equipmentId', $rootScope.equipmentId)
                form.append('projectCode', $rootScope.projectCode)
                form.append('imgFile', files[0])
                $http({
                    method: 'POST',
                    url: '/jsis/uploadPicture',
                    data: form,
                    headers: {'Content-Type': undefined},
                    transformRequest: angular.identity
                }).success(function (response) {
                    console.log('upload success111111', response);
                    $scope.bgImgWidget.data.value = response.data
                    $scope.imageSrc = response.data
                    $('#upload-img').attr('src', response.data)
                    $('#bgImgSrc').attr('src', response.data)
                    $scope.bgImgUrlDay = response.data // 白天模式
                    $scope.bgImgUrlNight = response.data // 黑夜模式
                    var imgIndex = $scope.devices[$scope.curIndex].widgets.findIndex(el => el.type == 2)
                    $scope.devices[$scope.curIndex].widgets[imgIndex].data.value =  response.data

                }).error(function (data) {
                    console.log('upload fail');
                })

            }else {
                // alert("文件尺寸应为:295*413(像素)!");
                toastr.warning('图片尺寸不符合,图片尺寸应为:'+ widthPix+'*'+heightPix+'(像素)')
                document.querySelector('input[type="file"]').value = "";
                return false;
            }
        };  
        image.src= data;  //img.src 应该是放在 onload 方法后边的, 因为当image的src发生改变,浏览器就会跑去加载这个src里的资源,先告诉浏览器图片加载完要怎么处理,再让它去加载图片
    };  
    reader.readAsDataURL(file);//读取文件并将文件数据以URL形式保存到result属性中。 读取图像常用
  };

 

elementUI  el-upload检测图片尺寸代码如下:

<template>
  <div v-loading="isLoading" class="uploadImg-globalParams">
    <el-upload
      :class="{'hideUpload': fileList.length>0, 'showUpload': fileList.length==0}"
      ref="upload"
      action="#"
      :http-request="handleFileUpload"
      list-type="picture-card"
      :headers="headers"
      accept="image/*"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-upload="beforeAvatarUpload"
      :on-exceed="handleExceed"
      :file-list="existFileList">
      <!-- <el-button size="small" type="primary">点击上传</el-button> -->
      <i class="el-icon-plus" style="width:70px;height:70px;line-height:67px;"></i>
      <!-- <template slot="trigger">
        <i v-show="showUploadBtn" class="el-icon-plus" style="width:70px;height:70px;line-height:67px;"></i>
      </template> -->
      <div slot="tip">
        <p class="tips" v-html="remark"></p>
      </div>
    </el-upload>
    <div v-show="isEdit">
      <i class="el-icon-check icon-check" @click="editParamValue()"></i>
      <i class="el-icon-close icon-close" @click="cancleDelete"></i>
    </div>
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
  import jportalCommon from '@/jportal-common-update'
  import {uploadPicture} from '@/api/park'
  let userStorageService = jportalCommon.userStorageService

  export default {
    props: {
      limit: {
        type: Number,
        default: 9,
        required: false
      },
      type: {
        type: String,
        default: 'V'
      },
      requestUrl: {
        type: String,
        default: "/jpark-cloud-center/api/jsis/park/uploadPicture", 
        // default: "/jpark-center-mgr/api/jsis/upload/upload2oss",
        required: false
      },
      projectCode: {
        type: String,
        default: ''
      },
      imgInfo: {
        type: Object,
        default: function(){return {}},
        required: false
      },
      // existFileList: {
      //   type: Array,
      //   default: function () {
      //     return [
      //       // {url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'},
      //       // {url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}
      //     ]
      //   },
      //   required: false
      // },
      tips: {
        type: String,
        default: '*请先选择小区才可上传图片'
      },
      acceptImgType: {
        type: Array,
        default: function () {
          return ["image/jpeg", "image/png"]
        },
        required: false
      }
    },
    data() {
      return {
        isLoading: false,
        //上传文件
        headers: {
          'orgCode': userStorageService.getUser().orgCode,
          'personId': userStorageService.getUser().personId,
          'personName': encodeURIComponent(userStorageService.getUser().personName),
          'jsToken': userStorageService.getToken().jsToken,
          'jsCurAccNo': userStorageService.getToken().jsCurAccNo
        },
        dialogImageUrl: '',
        dialogVisible: false,
        // 上传的图片
        fileList: [],
        // 删除之前的图片
        removeList: [],
        isEdit: false,
        supportFileWidth: '',
        supportFileHeight: '',
        remark: '',
        existFileList: [],
        showUploadBtn: false
      }
    },
    mounted () {
      // this.fileList = []
    },
    methods: {
      downloadFile(url, name) {
        let path = "/jpark-cloud-center/api/jsis/upload/downHttpFile?path=" + url + '&name=' + name;
        window.open(path);
      },
      cancleDelete () {
        this.isEdit = false
        this.$emit('cancelImg')
      },
      handleRemove (file, fileList) {
        console.log('删除', file, fileList);
        this.isEdit = true
        if (this.fileList.length > 1) {
          this.$refs.upload.clearFiles()
          this.fileList = []
        } else {
          // let index = 
          // this.fileList = 
          this.fileList = []
        }
        console.log('existFileList', this.existFileList, this.fileList)
        if (!this.fileList.length) {
          // this.$nextTick(() => {
          //   document.querySelector('.el-upload').style.display = 'block'
          // })
          this.showUploadBtn = true
          
        }

        this.$emit('update:fileList', this.fileList)
      },
      handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 ${this.limit} 张图片,本次选择了 ${files.length} 张图片,共选择了 ${files.length + fileList.length} 张图片`);
      },
      handleSuccess (response, file, fileList) {
        console.log('上传成功', this.$refs.upload.$el)
        if (response.respCode == 'success') {
          this.fileList.push({
                name: file.name|| new Date()-0,
                url: response.respData.url,
                path:response.respData.path
              })

              this.isEdit = true
        }
        this.$emit('update:fileList', this.fileList)
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      beforeAvatarUpload(file) {
        console.log('beforeAvatarUpload file', file)
        const isJPG = this.acceptImgType.includes(file.type);
        const isLt2M = file.size / 1024 / 1024 < 5;

        if (!isJPG) {
          this.$message.error('不支持此类型!'+'请上传'+this.acceptImgType.join('、')+'等类型文件');
          return false
        }
        
        if (!isLt2M) {
          this.$message.error('上传图片大小不能超过 5MB!');
          return false
        }
        // if (isJPG && isLt2M) {
        //   this.$message({
        //     message: `正在上传,请稍等...`,
        //     duration: 2000,
        //     type: 'success'
        //   })
        // }
        // 这个方法就是去限制上传图片的像素控制
        return this.checkImageWH(file, this.supportFileWidth, this.supportFileHeight);
        
      },
      // 处理文件上传操作
      handleFileUpload(file) {
        console.log('action', file)
        this.loading = true;
        let form = new FormData()
        form.append('imgFile', file.file)
        form.append('projectCode', this.projectCode)
        uploadPicture(form).then(resp => {
          console.log('图片上传成功', resp)
          if ("success" == resp.respCode) {
            this.fileList.push({url: resp.respData})
          }
        }).catch((e) => {
          this.$message.error(e.message);
          this.$refs.upload.clearFiles();
        })
      },
      // 配置图片像素
      checkImageWH(file, width, height) {
        let self = this;
        return new Promise(function (resolve, reject) {  // 文件读取异步函数变成同步执行
          let filereader = new FileReader();
          filereader.onload = (e) => {
            let src = e.target.result;
            const image = new Image();
            image.onload = function () {
              if (width && this.width !== Number(width)) {
                self.$message.warning(
                  "请上传宽为等于" + width + "像素的图片!"
                );
                reject();
              } else if (height && this.height !== Number(height)) {
                self.$message.warning(
                  "请上传高度等于" + height + "像素的图片!"
                );
                reject();
              } else {
                resolve();
              }
            };
            image.onerror = reject;
            image.src = src;
          };
          filereader.readAsDataURL(file);
        });
      },
      clearFiles() {
        this.fileList = [];
        this.$refs.upload.clearFiles();
      },
      editParamValue () {
        if (!this.fileList.length) {
          this.$message.warning('请上传背景图片')
          return
        }
        this.isEdit = false
        let data = {...this.imgInfo}
        data.paramValue = this.fileList[0].url
        this.$emit('updateParamImg', data)
      }
    },
    watch: {
      imgInfo:{
        deep: true, 
        handler: function (val, oval) {
          console.log('监听图片信息', val)
          this.supportFileWidth = val.pictureType.split('x')[0] || val.width
          this.supportFileHeight = val.pictureType.split('x')[1] || val.height
          this.remark = val.remark
          this.existFileList = val.imgUrl
          this.fileList = [...this.existFileList]
          console.log('this.existFileList', this.existFileList)
          this.$nextTick(() => {
            if (this.existFileList.length) {
              // document.querySelector('.el-upload').style.display = 'none'
            } else {
              // document.querySelector('.el-upload').style.display = 'block'
              this.showUploadBtn = true
            }
          })
          
        },
        immediate: true
      },
    },
    mounted() {
      
    }
  }
</script>
<style lang="scss">
.uploadImg {
  .is-disabled + .el-upload {
    cursor: not-allowed!important;
  }
  .is-disabled + .el-upload--picture-card:hover,.is-disabled + .el-upload:focus {
    border-color: #c0ccda;
    color: #c0ccda;
  }
}
.uploadImg-globalParams {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  .el-upload--picture-card,.el-upload-list__item {
    width: 70px;
    height: 70px;
    line-height: 67px;
  }
  .icon-check {
    padding: 0 10px;
    color: #67c23a;
    cursor: pointer;
  }
}

</style>
<style lang='scss' scoped>
.tips{
  color: #F56C6C;line-height: 1.5;
}
.hideUpload /deep/ .el-upload{
    display:none;   
}
.showUpload /deep/ .el-upload{
    display:block;  
}
.uploadImg-globalParams ::v-deep .el-upload-list__item {
  transition: none !important;
}
</style>