Bootstrap

跨平台应用开发进阶 (四) :uni-app 实现图片上传、预览、删除、压缩

一、前言

应用开发跨平台App项目时,上传图片、文档等资源功能需求十分常见:点击相框按钮可选择图片上传,点击每一个图片可以进行预览,点击每个图片删除图标可删除对应图片。基本实现功能点如下:

  • 本地相册选择图片或使用相机拍照上传图片;

  • 可以预览选择上传的图片;

  • 删除选错或不选的图片;

二、项目实战

经过研读门户,官网推荐应用接口从本地相册选择图片或使用相机拍照。

对于门户提到的

选择照片大多为了上传,封装了更完善的组件,文件选择、上传到的免费存储和cdn中,一站式集成。强烈推荐使用。

⚠️本人并不认可,经过实践可知,该接口只能实现客户端将图片资源上传到后台服务器中,并不支持本地服务器,故并不满足功能需求,需谨慎使用。

项目实现页面大致逻辑如下,完整页面实现逻辑可移步《》下载。

视图渲染


JS逻辑层-图片上传

// 图片选择上传
upload() {
  var _self = this;
  // 图片选择,只支持一次选择一张图片
  uni.chooseImage({
    count: 1,
    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
    sourceType: ['album', 'camera'], //从相册、相机选择
    success: function (res) {
      console.log('res:', res)
      _self.curTotal++;
      _self.imgList.push(res.tempFilePaths[0]);
      const tempFilePaths = res.tempFilePaths[0];
      // 图片上传
      const uploadTask = uni.uploadFile({
        url : 'http://22.189.25.91:9988/admin/sys-file/upload', // post请求地址
          filePath: tempFilePaths,
          name: 'file',  // 待确认
          header: {
          'Content-Type': 'multipart/form-data',
          'Authorization': getApp().globalData.token || 'Basic YXBwOmFwcA=='
        },
        success: function (uploadFileRes) {
          console.log('Success:', uploadFileRes);
          _self.imgsID.push(JSON.parse(uploadFileRes.data).data.fileId);
          console.log('_self.imgsID:', _self.imgsID)
        },
        fail: function (uploadFileFail) {
          console.log('Error:', uploadFileFail.data);
        },
        complete: ()=> {
          console.log('Complete:');
        }
      });
    },
    error : function(e){
      console.log(e);
    }
   });
}

JS逻辑层-图片预览

/**
 * 图片预览
 * @param {Object} i 选择的图片索引
 * @param {Object} imgList 自行封装的图片数组
 */
viewImage(i, imgList) {
  let imgurl = []
  imgList.forEach(item => imgurl.push(item))
  uni.previewImage({
    urls: imgurl,
    current: imgList[i]
  });
}

JS逻辑层-图片删除

/** 图片删除
 * @param {Object} i 删除图片的索引
 * @param {Object} imgList 自行封装的图片数组
 */
delImg(i, imgList, imgsID) {
  uni.showModal({
    title: '提示',
    content: '确定要删除照片吗?',
    cancelText: '取消',
    confirmText: '确定',
    success: res => {
      if(res.confirm) {
        imgList.splice(i, 1);
        imgsID.splice(i, 1);
        this.curTotal--;
      }
    }
  })
}
}

JS逻辑层-图片压缩

// src: 压缩转换原始图片的路径
// _this: 当前的this,如果不想传递this可将该函数改为箭头函数
// callback: 回调函数,详情chooseImage方法
function compressImage(src, _this, callback) {
  var dstname = "_doc/IMG-" + (new Date()).valueOf() + ".jpg"; //设置压缩后图片的路径 
  var width, height, quality;
  width = "80%";
  height = "80%";
  quality = 80;
  // 具体情况可查看HTML5+文档 ===> http://www.html5plus.org/doc/zh_cn/zip.html#plus.zip.compressImage
  plus.zip.compressImage({
      src: src,
      dst: dstname,
      overwrite: true,
      quality: quality,
      width: width,
      height: height
    },
    function(event) {
      callback(event.target, dstname, _this);
    },
    function(error) {
      return src;
    });
}

注意⚠️:在图片上传之前进行图片压缩,由于图片压缩时间过长,应采用上传图片之前先压缩,否则上传会比压缩先执行。

应用实现效果如下:拍照或从相册选择图片/上传一张图片

上传3张图片/删除图片

三、知识点总结

3.1 实现原理

客户端通过方法选择本地相册图片或者拍照,获取到一个本地资源的临时文件路径后,然后以 请求方式通过方法将本地资源上传到开发者服务器, 请求中 为 。

3.2 注意事项

  • ⚠️图片选择应用实现,请谨慎使用封装的所谓更完善的组件,其将资源文件选择、上传到的免费存储和中,一站式集成,个人无法修改。强烈推荐不使用!

  • ⚠️图片上传应用实现,上传成功后回调函数返回的是个类型,转对象的时候需要应用解析。

  JSON.parse(uploadFileRes.data).data.fileId)

  {
    "data": "{\"code\":0,\"msg\":null,\"data\":{\"bucketName\":\"cicc\",\"fileName\":\"5aaa39d669224ffb869b60d245b0751a.jpg\",\"original\":\"1644999553865_mmexport1644913914292.jpg\",\"url\":\"/admin/sys-file/cicc/5aaa39d669224ffb869b60d245b0751a.jpg\",\"fileId\":\"172\"}}",
    "statusCode": 200,
    "errMsg": "uploadFile:ok"
  }

  • OBJECT 参数说明部分中属性为待上传文件对应的 , 开发者在服务器端通过这个 可以获取到文件二进制内容,前后端对于该key应保持一致,否则会导致服务无法请求。

  • 图片预览应用实现,没遇到坑,大家可根据需求按照门户参数使用。

四、学习一隅