微信小程序压缩图片并上传

wxml

<canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
<view style="text-align: center;"><image style="width: 192rpx;height: 192rpx;border-radius: 500rpx !important;overflow: hidden;	margin-top: 30rpx;margin-bottom: 30rpx;" src="{{returnImage}}"></image></view>
<view style="display: flex;">
	<button type="primary" bindtap="getImageInfo">头像预览</button>
	<button type="primary" bindtap="upload" loading="{{isdisabled}}" disabled="{{isdisabled}}">上传头像</button>
</view>

js

const app = getApp();
// 手机的宽度
var windowWRPX = 750
var pixelRatio = wx.getSystemInfoSync().pixelRatio
Page({
  /**
   * 页面的初始数据
   */
  data: {
    topLabel: '头像上传', //顶部栏
    triggered: false, //模块是否刷新中
    isdisabled: false, //是否提交
    showmodel: false, //是否编辑模式
    imageSrc: '',
    returnImage: '',
    isShowImg: false,
    // 初始化的宽高
    cropperInitW: windowWRPX,
    cropperInitH: windowWRPX,
    // 动态的宽高
    cropperW: windowWRPX,
    cropperH: windowWRPX,
    // 动态的left top值
    cropperL: 0,
    cropperT: 0,
    // 图片缩放值
    scaleP: 0,
    imageW: 0,
    imageH: 0,
    // 裁剪框 宽高
    cutW: 0,
    cutH: 0,
    cutL: 0,
    cutT: 0,
  },
  upload(e) { //头像上传
    wx.showLoading({
      title: '头像上传中...',
    })
    this.setData({isdisabled:true})
    const userinfo = wx.getStorageSync('userinfo')
    let encryptor = new Encrypt.JSEncrypt()
    encryptor.setPublicKey(publicKey);
    let requestkey = encryptor.encrypt(userinfo.YHBH + ',' + userinfo.OPENID + ',' + userinfo.BH + ',' + new Date().getTime()) // 加密
    // 将图片写入画布
    const ctx = wx.createCanvasContext('myCanvas')
    ctx.drawImage(this.data.imageSrc)
    ctx.draw(true, () => {
      // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
      let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
      let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
      let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
      let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
      setTimeout(() => {
        wx.canvasToTempFilePath({
          x: canvasL,
          y: canvasT,
          width: canvasW,
          height: canvasH,
          destWidth: canvasW * 0.35,//设置压缩百分比,如果写100就是分辨率
          destHeight: canvasH * 0.35,//设置压缩百分比,如果写100就是分辨率
          canvasId: 'myCanvas',
          fileType: 'jpg',
          success: res => {
            wx.uploadFile({
              url: App.uploads + '/weixin/upload/img/upload/cover',
              filePath: res.tempFilePath,
              name: 'file',
              header: {
                token: requestkey
              },
              formData: {
                BH: wx.getStorageSync('userinfo').BH
              },
              success:res=>{
                res.data = JSON.parse(res.data)
                let pages = getCurrentPages();
                let previousPage = pages[pages.length - 2]; //上一个页面
                previousPage.setData({
                  avatarUrl: res.data.data.filePath
                })
                const userinfo = wx.getStorageSync('userinfo')
                userinfo.TX = res.data.data.filePath
                wx.setStorageSync('userinfo', userinfo)
                wx.hideLoading()
                wx.showToast({
                  title: '上传成功',
                  icon: "succes",
                  duration: 1500
                })
                this.setData({isdisabled:false})
              },
              fail:res=>{
                this.setData({isdisabled:false})
                wx.hideLoading()
                wx.showToast({
                  title: '上传失败',
                  icon: "error",
                  duration: 1500
                })
              }
            })
          }
        })
      }, 500);
    })
  },
  // 获取图片
  getImageInfo() {
    wx.showLoading({
      title: '图片生成中...',
    })
    wx.downloadFile({
      url: this.data.imageSrc, //仅为示例,并非真实的资源
      success: res=>{
    // 将图片写入画布
      const ctx = wx.createCanvasContext('myCanvas')
      ctx.drawImage(res.tempFilePath)
      ctx.draw(true, () => {
        // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
        let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
        let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
        let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
        let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
        setTimeout(() => {
          wx.canvasToTempFilePath({
            x: canvasL,
            y: canvasT,
            width: canvasW,
            height: canvasH,
            destWidth: canvasW * 0.35,//设置压缩百分比,如果写100就是分辨率
            destHeight: canvasH * 0.35,//设置压缩百分比,如果写100就是分辨率
            canvasId: 'myCanvas',
            fileType: 'jpg',
            success: res=>{
              wx.hideLoading()
              // wx.getImageInfo({
              //   src: res.tempFilePath,
              //   success (res) {
              //     console.log(res.width)//图片宽
              //     console.log(res.height)//图片高
              //   }
              // })
              // 成功获得地址的地方
              wx.previewImage({
                current: '', // 当前显示图片的http链接
                urls: [res.tempFilePath] // 需要预览的图片http链接列表
              })
              this.setData({
                returnImage:res.tempFilePath
              })
            }
          })
        }, 200);
      })
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({
      imageSrc: 'https://wx3.sinaimg.cn/orj360/6b03f0e6gy1h6c1mivf4lj20u01400wu.jpg'
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
    onReady: function () {
    wx.showLoading({
      title: '图片加载中...',
    })
    wx.getImageInfo({
      src: this.data.imageSrc,
      success: res=>{
        var innerAspectRadio = res.width / res.height;
        // 根据图片的宽高显示不同的效果   保证图片可以正常显示
        if (innerAspectRadio >= 1) {
          this.setData({
            cropperW: windowWRPX,
            cropperH: windowWRPX / innerAspectRadio,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
            // 裁剪框  宽高  
            cutW: windowWRPX,
            cutH: windowWRPX / innerAspectRadio,
            cutL: 0,
            cutT: 0,
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        } else {
          this.setData({
            cropperW: windowWRPX * innerAspectRadio,
            cropperH: windowWRPX,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
            // 裁剪框的宽高
            cutW: windowWRPX * innerAspectRadio,
            cutH: windowWRPX,
            cutL: 0,
            cutT: 0,
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        }
        this.setData({
          isShowImg: true
        })
        wx.hideLoading()
      }
    })
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  }
})

实际应用场景

wxml

<canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
<button class="round cu-avatar" plain="true" open-type="chooseAvatar" bind:chooseavatar="getimginfo" style="border: 0;width: 158rpx;height: 158rpx;">
    <image class="round" src="https://wx3.sinaimg.cn/orj360/6b03f0e6gy1h6c1mivf4lj20u01400wu.jpg" style="width: 158rpx;height: 158rpx;"></image>
</button>

js

const app = getApp();
// 手机的宽度
var windowWRPX = 750
var pixelRatio = wx.getSystemInfoSync().pixelRatio
Page({
  /**
   * 页面的初始数据
   */
  data: {
    topLabel: '头像上传', //顶部栏
    // 初始化的宽高
    cropperInitW: windowWRPX,
    cropperInitH: windowWRPX,
    // 动态的宽高
    cropperW: windowWRPX,
    cropperH: windowWRPX,
    // 动态的left top值
    cropperL: 0,
    cropperT: 0,
    // 图片缩放值
    scaleP: 0,
    imageW: 0,
    imageH: 0,
    // 裁剪框 宽高
    cutW: 0,
    cutH: 0,
    cutL: 0,
    cutT: 0,
  },
    getimginfo(e) { //获取图片信息
    wx.getImageInfo({
      src: e.detail.avatarUrl,
      success: res => {
        var innerAspectRadio = res.width / res.height;
        // 根据图片的宽高显示不同的效果   保证图片可以正常显示
        if (innerAspectRadio >= 1) {
          this.setData({
            cropperW: windowWRPX,
            cropperH: windowWRPX / innerAspectRadio,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
            // 裁剪框  宽高  
            cutW: windowWRPX,
            cutH: windowWRPX / innerAspectRadio,
            cutL: 0,
            cutT: 0,
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        } else {
          this.setData({
            cropperW: windowWRPX * innerAspectRadio,
            cropperH: windowWRPX,
            // 初始化left right
            cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
            cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
            // 裁剪框的宽高
            cutW: windowWRPX * innerAspectRadio,
            cutH: windowWRPX,
            cutL: 0,
            cutT: 0,
            // 图片缩放值
            scaleP: res.width * pixelRatio / windowWRPX,
            // 图片原始宽度 rpx
            imageW: res.width * pixelRatio,
            imageH: res.height * pixelRatio
          })
        }
        this.upfile(e.detail.avatarUrl)
      }
    })
  },
  upfile(url) { //上传图片
    wx.getFileInfo({
      filePath: url,
      success: res => {
        if (res.size > 10000) { //大于10KB就压缩
          const ctx = wx.createCanvasContext('myCanvas')
          ctx.drawImage(url)
          ctx.draw(true, () => {
            // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题
            let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
            let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
            let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
            let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
            setTimeout(() => {
              wx.canvasToTempFilePath({
                x: canvasL,
                y: canvasT,
                width: canvasW,
                height: canvasH,
                destWidth: canvasW * 0.35, //设置压缩百分比,如果写100就是分辨率
                destHeight: canvasH * 0.35, //设置压缩百分比,如果写100就是分辨率
                canvasId: 'myCanvas',
                fileType: 'jpg',
                success: res => {
                  wx.uploadFile({
                    url: App.uploads + '/file/api/upload',
                    filePath: res.tempFilePath,
                    name: 'file',
                    header: {
                      authToken: wx.getStorageSync('token'),
                    },
                    success: res => {
                      res.data = JSON.parse(res.data)
                      this.data.tx = res.data.data.filePath
                      this.batchmodify()
                    },
                    fail: res => {
                      wx.hideLoading()
                      wx.showToast({
                        title: '上传失败',
                        icon: "error",
                        duration: 1500
                      })
                    }
                  })
                }
              })
            }, 500);
          })
        } else {
          wx.uploadFile({
            url: App.uploads + '/file/api/upload',
            filePath: url,
            name: 'file',
            header: {
              authToken: wx.getStorageSync('token'),
            },
            success: res => {
              res.data = JSON.parse(res.data)
              this.data.tx = res.data.data.filePath
              this.batchmodify()
            },
            fail: res => {
              wx.hideLoading()
              wx.showToast({
                title: '上传失败',
                icon: "error",
                duration: 1500
              })
            }
          })
        }
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  }
})

css

.round {
    border-radius: 5000rpx !important;
    overflow: hidden;
}
.cu-avatar {
    font-variant: small-caps;
    margin: 0;
    padding: 0;
    display: inline-flex;
    text-align: center;
    justify-content: center;
    align-items: center;
    background-color: #ccc;
    color: var(--white);
    white-space: nowrap;
    position: relative;
    width: 64rpx;
    height: 64rpx;
    background-size: cover;
    background-position: center;
    vertical-align: middle;
    font-size: 1.5em;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值