在一些相机设备中因手持方向的原因导致图片会有一个旋转角度,在图片加载后旋转角度被忽略了,导致图片看过去是旋转的,
小程序中不需要借助任何工具获取图片信息,通过wx.getImageInfo()获取orientation
orientation值有四个
- up 不需要旋转
- down 旋转180度
- left 旋转270度
- right 旋转90度
小程序中处理图片旋转条件
- 需要在wxml中添加canvas组件
- 设置canvas-id属性
- 为了让这个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 组件
})
}
})
}
})
}
}
})
效果展示