小程序中解决图片旋转问题

在一些相机设备中因手持方向的原因导致图片会有一个旋转角度,在图片加载后旋转角度被忽略了,导致图片看过去是旋转的,
小程序中不需要借助任何工具获取图片信息,通过wx.getImageInfo()获取orientation
orientation值有四个
在这里插入图片描述

  1. up 不需要旋转
  2. down 旋转180度
  3. left 旋转270度
  4. right 旋转90度

小程序中处理图片旋转条件

  1. 需要在wxml中添加canvas组件
  2. 设置canvas-id属性
  3. 为了让这个canvas不显示,设置绝对定位并定位在显示区外
<button  catchtap="onUploadAction">选择图片</button>
<view>旋转前</view>
<image class="rotateBefore" src="{{rotateBefore}}" mode="aspectFit"></image>
<view>旋转后</view>
<image class="rotateAfter" src="{{rotateAfter}}" mode="aspectFit"></image>

<!-- 请注意canvas组件属性 -->
<canvas canvas-id="my-canvas" 
style="width:{{canvasWidth}}px;height:{{canvasHeight}}px;position:absolute;top:-2000%;">
</canvas>
// components/upload-img/index.js
Component({
  data: {
    rotateBefore: null,
    rotateAfter: null,
    canvasWidth:null,
    canvasHeight:null
  },
  methods: {
    onUploadAction(e) { // 选择图片
      let _this = this
      wx.showActionSheet({
        itemList: ['从相册中选择', '拍照'], // 选择方式
        success: function(res) {
          if (!res.cancel) {
            if (res.tapIndex == 0) {
              _this.chooseWxImage('album')
            } else if (res.tapIndex == 1) {
              _this.chooseWxImage('camera')
            }
          }
        }
      })
    },
    chooseWxImage(type) {
      let _this = this;
      wx.chooseImage({
        sizeType: ['original', 'compressed'],
        sourceType: [type],
        success: function(result) {
          let tempFilePaths = result.tempFilePaths // 获得文件地址
          //  旋转前
          _this.setData({
            rotateBefore: tempFilePaths[0] // 设置旋转前的image
          })
          wx.getImageInfo({ // 获取图片的信息
            src: tempFilePaths[0],
            success: (res) => {
              let canvasContext = wx.createCanvasContext('my-canvas', _this)
              // 下面按比例写死宽度高度是为了压缩图片提升上传速度,可按实际需求更改
              let rate = res.height / res.width 
              let width = 500
              let height = 500 * rate
              switch (res.orientation) { // 根据orientation值处理图片
                case ("up"):
                  //不需要旋转
                  _this.setData({
                    canvasWidth: width,
                    canvasHeight: height,
                  })
                  canvasContext.drawImage(tempFilePaths[0], 0, 0, width, height);
                  break;
                case ("down"):
                  //需要旋转180度
                  _this.setData({
                    canvasWidth: width,
                    canvasHeight: height,
                  })
                  canvasContext.translate(width / 2, height / 2)
                  canvasContext.rotate(180 * Math.PI / 180)
                  canvasContext.drawImage(tempFilePaths[0], -width / 2, -height / 2, width, height);
                  break;
                case ("left"):
                  //顺时针旋转270度
                  _this.setData({
                    canvasWidth: height,
                    canvasHeight: width,
                  })
                  canvasContext.translate(height / 2, width / 2)
                  canvasContext.rotate(270 * Math.PI / 180)
                  canvasContext.drawImage(tempFilePaths[0], -width / 2, -height / 2, width, height);
                  break;
                case ("right"):
                  //顺时针旋转90度
                  _this.setData({
                    canvasWidth: height,
                    canvasHeight: width,
                  })
                  canvasContext.translate(height / 2, width / 2)
                  canvasContext.rotate(90 * Math.PI / 180)
                  canvasContext.drawImage(tempFilePaths[0], -width / 2, -height / 2, width, height)
                  break;
              }
              canvasContext.draw(false, () => { // 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
                wx.canvasToTempFilePath({ // 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
                  canvasId: 'my-canvas',
                  success(res) {
                    let filePath = res.tempFilePath
                    _this.setData({
                      rotateAfter: filePath
                    })
                  }
                }, _this)// 在自定义组件下,当前组件实例的this,以操作组件内 canvas 组件
              })
            }
          })
        }
      })
    }
  }
})

效果展示
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值