微信小程序图片选择、压缩、上传、删除

在这里插入图片描述

wxml

 <canvas type="" id="compressCanvas" canvas-id="compressCanvas" style="position: absolute;top: -100000rpx;z-index: -10000;width: {{width}}px;height: {{height}}px;" />

   <view wx:if="{{!img}}" class="upload flex-column-center" bind:tap="chooseImageAndUpload" data-img="img">
      <image catch:tap="chooseImageAndUpload" data-img="img" src="../../static/images/upload.png" mode="" />
      <text catch:tap="chooseImageAndUpload" data-img="img">请上传行驶证正面</text>
    </view>
    <image bind:tap="previewImage" data-img="img" class="" style="width: 300rpx;height: 200rpx;border-radius: 30rpx;margin-top: 15rpx;position: relative;" wx:else src="{{img}}" mode="">
      <image bind:tap="del" data-img="img" style="position: absolute;right: 20rpx;top: 20rpx;width: 50rpx;height: 50rpx;" src="../../static/images/close.png" mode="" />
    </image>

wxss

.topone image {
  width: 50rpx;
  height: 50rpx;
  margin-bottom: 10rpx;
}

.flex-column-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

这里将

1.图片选择,

2.压缩

3.上传

4.删除(可以只删除提交前的数据,想从服务器中删除需要调用接口)

等方法统一封装在混入中

const MyUploadImgMixin = {
  methods: {


  // 图片选择
    async chooseImageAndUpload(e) {
      console.log(e.target.dataset.img);

      wx.chooseMedia({
        count: 1,
        // 最多可以选择的文件个数,基础库2.25.0前,最多可支持9个文件,2.25.0及以后最多可支持20个文件
        mediaType: ['image'],
        // 	只能拍摄图片或从相册选择图片
        sizeType: ['compressed'],
        // 是否压缩所选文件
        sourceType: ['album', 'camera'],
        // 图片和视频选择的来源
        // maxDuration: 30,
        // 拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 60s 之间。不限制相册。
        camera: 'back',
        // 仅在 sourceType 为 camera 时生效,使用前置或后置摄像头
        success: async (res) => {
          console.log(res);
          const tempFilePath = res.tempFiles[0].tempFilePath;
          console.log(tempFilePath);
          try {
            // 压缩图片
            console.log(e.target.dataset.img, 'e.target.dataset.img');
            const compressedFilePath = await this.compressImage(tempFilePath, e.target.dataset.img);
            console.log('压缩后的图片路径:', compressedFilePath);

            // 这里可以添加上传图片的逻辑
            // 示例:使用wx.uploadFile上传压缩后的图片到服务器
            // await this.uploadCompressedImage(compressedFilePath);
          } catch (error) {
            console.error('图片压缩时发生错误:', error);
          }
        },
        fail: (err) => {
          console.error('选择图片失败:', err);
        },
      });
    },




    // 图片压缩
    compressImage(tempFilePath, e) {
      let that = this

      // 获取系统信息,用于计算压缩比例
      wx.getImageInfo({
        src: tempFilePath,
        success: function (res) {
          console.log(res);
          const width = res.width
          const height = res.height
          // 使用Canvas进行图片压缩
          const canvasId = 'compressCanvas';
          const ctx = wx.createCanvasContext(canvasId);
          // ctx.drawImage(tempFilePath, 0, 0, width < 300 ? width : 300, height < 150 ? height : 150);
          ctx.drawImage(tempFilePath, 0, 0, width, height);
          ctx.draw(false, () => {
            // 将canvas内容导出为临时文件,实现压缩
            wx.canvasToTempFilePath({
              canvasId: canvasId,
              // width: width,
              // height: height,
              // 画布标识,传入 canvas 组件的 canvas-id
              // destWidth: width, // 输出的图片的宽度 width*屏幕像素密度
              // destHeight: height,
              // quality: 0.9,
              fileType: 'jpg', // 目标文件的类型
              success: function (res) {
                const compressedFilePath = res.tempFilePath;
                console.log('图片压缩成功,路径为:', compressedFilePath);
                
                // // 保存到本地
                // wx.saveImageToPhotosAlbum({
                //   filePath: compressedFilePath,
                // })

                // 上传到服务器之前,可以用临时地址预览,可以上传之后,改为上传之后返回地址预览
                console.log(e);
                let propName = e;
                // 构建一个动态的对象
                let dataToUpdate = {};
                dataToUpdate[propName] = compressedFilePath; // 动态设置属性名和值
                console.log(dataToUpdate);
                that.setData(dataToUpdate);

                // 这里可以进行图片上传操作
                that.uploadCompressedImage(compressedFilePath);
              },
              fail: function (err) {
                console.error('图片压缩失败', err);
              }
            });
          });
        }
      });
    },



    // 图片上传
    uploadCompressedImage(filePath) {
      wx.uploadFile({
        url: '你的上传接口地址', // 服务器上传接口地址
        filePath: filePath,
        name: 'file', // 对应后台接收文件的字段名
        formData: {
          // 其他额外表单数据
        },
        success: (uploadResult) => {
          console.log('图片上传成功', uploadResult);
          // 解析服务器响应
          const data = JSON.parse(uploadResult.data);
          if (data.success) {
            wx.showToast({
              title: '上传成功',
              icon: 'success',
              duration: 2000,
            });
          } else {
            wx.showToast({
              title: '上传失败',
              icon: 'none',
              duration: 2000,
            });
          }
        },
        fail: (err) => {
          console.error('图片上传失败:', err);
          wx.showToast({
            title: '上传失败',
            icon: 'none',
            duration: 2000,
          });
        },
      });
    },



    previewImage(e) {
      wx.previewImage({
        current: this.data[e.target.dataset.img], // 当前显示图片的链接
        urls: [this.data[e.target.dataset.img]] // 需要预览的图片链接列表
      })
    },



    del(e) {
      // 假设你有一个条件来决定更新哪个属性
      let propName = e.target.dataset.img; // 或者根据条件动态决定如:condition ? 'img' : 'alternativeProp'

      // 构建一个动态的对象
      let dataToUpdate = {};
      dataToUpdate[propName] = null; // 动态设置属性名和值

      // 使用这个动态对象调用setData
      this.setData(dataToUpdate);

    },
  },
};
module.exports = MyUploadImgMixin;

注意

这里点击选择图片时候,会有点击事件的问题,因为里面有两个元素,所以也要定义点击事件,而已要使用catch:tap阻止事件冒泡

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值