微信小程序上传图片裁剪

上传图片裁剪

    

 

 一、we-cropper 一款灵活小巧的canvas图片裁剪器

克隆至本地处理

git clone https://github.com/we-plugin/we-cropper.git

npm方式引入

npm install we-cropper --save

图片裁剪常用于头像选择和图片合成等。

插件下载:GitHub - we-plugin/we-cropper: 微信小程序图片裁剪工具

参考教程:we-cropper - 小程序图片裁剪工具
文档:https://we-plugin.github.io/we-cropper/#/

图片裁剪解决方案:

目前网络上知名的微信小程序图片裁剪插件是we-cropper

操作步骤:下载好we-cropper文件夹,拷贝到小程序目录,可以放在pages列表中。
参考例子:example文件夹下面直接引入参考

二、自定义实例

1.在pages中创建imgcorp.wxml文件,将下载的we-cropper文件拷贝到pages中
imgcorp.wxml
<import src="/pages/we-cropper/index.wxml" />
<!-- 上传图片未裁剪时 -->
<block wx:if="{{!cropImgInfo.imgUrl}}">
  <view class="cropper-wrapper">
    <view class="wecropper">
      <template is="we-cropper" data="{{...cropperOpt}}" />
    </view>
    <view class="cropper-buttons">
      <view class="upload btn" catchtap="uploadTap">上传图片</view>
      <view class="getCropperImage btn" catchtap="getCropperImage">生成图片</view>
    </view>
  </view>
</block>

<!-- 已裁剪图片 -->
<block wx:if="{{cropImgInfo.imgUrl}}">
  <view class="cropper-wrapper" style="background: #202020;">
    <image src="{{cropImgInfo.imgUrl}}" class="cropper-img" mode="widthFix"></image>
    <view class="cropper-buttons">
      <view class="upload btn" catchtap="onCancelImg">取消</view>
      <view class="getCropperImage btn" catchtap="onConfirmImg">确定</view>
    </view>
  </view>
</block>

imgcorp.wxss

.cropper-wrapper {
  position: relative;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: #e5e5e5;
}

.cropper {
  width: 100%;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
}

.cropper-img {
  display: block;
  width: 100%;
}

.cropper-buttons {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 999999999;
  width: 100%;
  height: 55px;
  padding: 0 40rpx;
  box-sizing: border-box;
  line-height: 55px;
  background-color: rgba(0, 0, 0, 0.9);
}

.btn {
  height: 60rpx;
  line-height: 60rpx;
  padding: 0 24rpx;
  border-radius: 4rpx;
  color: #ffffff;
}

.upload,
.getCropperImage {
  text-align: center;
}

imgcorp.js

// pages/we-cropper/imgcorp.js
const dataMainModule = require('../../utils/main.js');
const common = require('../../utils/common.js');
const WeCropper = require('./index.js');
const device = wx.getSystemInfoSync(); // 获取设备信息
const width = device.windowWidth // 示例为一个与屏幕等宽的正方形裁剪框
const height = device.windowHeight - 55;
const croWidth = width * 0.8;

Page({
  data: {
    isfrom: null, //页面来源
    isfiles: null, //是否是其他页面上传图片过来
    tempFiles: null, //其他页面上传图片信息
    fileSize: 10, //上传图片文件大小
    cropperOpt: {
      id: 'cropper', // 用于手势操作的canvas组件标识符
      targetId: 'targetCropper', // 用于用于生成截图的canvas组件标识符
      pixelRatio: device.pixelRatio, // 传入设备像素比
      width, // 画布宽度
      height, // 画布高度
      scale: 2.5, // 最大缩放倍数
      zoom: 8, // 缩放系数
      cut: {
        x: (width - croWidth) / 2, // 裁剪框x轴起点
        y: (height - croWidth) / 2, // 裁剪框y轴期起点
        width: croWidth, // 裁剪框宽度
        height: croWidth // 裁剪框高度
      }
    },
    imgUrl: null, //是否有上传图片
    cropImgInfo: {
      url: null, //裁剪过的图片
      imgUrl: null, //裁剪过的图片全地址
      fileType: null, //图片类型
    },
  },
  cropper: null,
  onLoad: function (options) {
    wx.removeStorageSync('cropImgInfo');
    if (options) {
      if (options.isfrom) {
        this.setData({
          isfrom: options.isfrom
        })
      }
      if (options.fileSize) {
        this.setData({
          fileSize: options.fileSize
        })
      }
      if (options.fileType) {
        this.setData({
          ['cropImgInfo.fileType']: options.fileType
        })
      }
      if (options.isfiles) {
        var tempFiles = common.copyVueData(JSON.parse(wx.getStorageSync('tempFiles')));
        this.setData({
          isfiles: options.isfiles,
          tempFiles: tempFiles,
          imgUrl: tempFiles.path
        })
        wx.removeStorageSync('tempFiles');
      }
    }
    if (this.data.isfiles) {
      this.init(this.data.tempFiles);
    } else {
      this.init();
    }
  },
  init(tempFiles) {
    //实例化裁剪图片
    const {
      cropperOpt
    } = this.data
    this.cropper = new WeCropper(cropperOpt)
      .on('ready', (ctx) => {
        console.log(`wecropper is ready for work!`)
      })
      .on('beforeImageLoad', (ctx) => {
        common.loading(true, '上传中');
      })
      .on('imageLoad', (ctx) => {
        common.loading(false);
      })
    this.cropper.updateCanvas();
    if (!common.isEmpty(tempFiles)) {
      this.initWeCropper(tempFiles);
    }
  },
  initWeCropper(tempFiles) {
    //显示图片
    if (tempFiles) {
      this.cropper.pushOrign(tempFiles.path);
    }
  },
  touchStart(e) {
    this.cropper.touchStart(e);
  },
  touchMove(e) {
    this.cropper.touchMove(e);
  },
  touchEnd(e) {
    this.cropper.touchEnd(e);
  },
  uploadTap() {
    // 上传图片
    let that = this;
    wx.chooseImage({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: res => {
        let tempFiles = res.tempFiles[0];
        if (common.getIsfileSize(tempFiles.size, that.data.fileSize)) {
          return;
        }
        that.setData({
          imgUrl: tempFiles.path
        })
        that.initWeCropper(tempFiles);
      }
    })
  },
  getCropperImage() {
    //生成图片
    let that = this;
    if (common.isEmpty(this.data.imgUrl)) {
      common.getToast('请先上传图片');
      return;
    }
    common.loading(true, '正在生成图片');
    this.cropper.getCropperImage() //裁剪临时图片文件
      // this.cropper.getCropperBase64() //裁剪base64图片文件
      .then((res) => {
        if (res) {
          that.getUploadFile(res); //上传临时图片
          // that.uploadHsFile(res); //上传base64图片
        } else {
          common.getToast('生成图片失败,请稍后重试')
        }
      }).catch((err) => {
        wx.showModal({
          title: '温馨提示',
          content: err.message
        })
      })
  },
  getUploadFile(imgUrl) {
    //上传服务器图片-临时文件
    let that = this;
    var temp = {
      url: imgUrl
    }
    common.loading(true, '正在生成图片');
    dataMainModule.getUploadFile(temp, (res) => {
      common.loading(false);
      if (res.retCode == 200) {
        if (res.retData) {
          var retItem = res.retData[0];
          that.setData({
            ['cropImgInfo.url']: retItem.fileReturnId,
            ['cropImgInfo.imgUrl']: common.getViewImageUrl(retItem.fileReturnId)
          })
        }
      }
    }, (res) => {
      common.loading(false);
      common.getToast(res);
    })
  },
  uploadHsFile(imageData) {
    //上传服务器图片-base64
    let that = this;
    let temp = {
      imageData: imageData
    }
    common.loading(true, '正在生成图片');
    dataMainModule.uploadHsFile(temp, (res) => {
      common.loading(false);
      if (res.retCode == 200) {
        if (res.data) {
          that.setData({
            ['cropImgInfo.url']: res.data,
            ['cropImgInfo.imgUrl']: common.getViewImageUrl(res.data)
          })
        }
      }
    }, (res) => {
      common.loading(false);
      common.getToast(res);
    })
  },
  onConfirmImg() {
    //确定
    if (this.data.cropImgInfo.imgUrl) {
      wx.setStorageSync('cropImgInfo', JSON.stringify(this.data.cropImgInfo));
      this.getBack();
    } else {
      common.getToast('请先生成图片');
    }
  },
  onCancelImg() {
    //取消裁剪图片
    this.setData({
      cropImgInfo: {
        url: null,
        imgUrl: null,
      },
      imgUrl: null,
    })
    setTimeout(() => {
      this.init();
    }, 300);
  },
  getBack() {
    //返回
    common.getWxBack();
  },

})
posted @ 2022-06-29 18:15  时光独醒  阅读(320)  评论(0编辑  收藏  举报