核心步骤
使用drawImage
方法将图片绘制到canvas上,并放在视图外,用户实际看到的是img标签所展示的图片,获取裁剪区域的四个点坐标,使用canvasToTempFilePath
API根据坐标导出相应的图片。
注意事项
将图片绘制到canvas上时为了避免原图大于实际显示的canvas大小,从而导致导出的图片模糊,要根据原图实际宽高按情况绘制canvas大小,并保持原图的宽高比。
展示效果
具体实现
获取实际图片的相关信息,并计算宽高比1
2
3
4
5
6
7
8
9
10
11
12
13
14
15uni.getImageInfo({
src: this.photoList[i].tempImagePath // 图片地址
}).then(([err, res]) => {
const { width, height } = res
this.whRatio = width / height // 计算宽高比
// this.whRatio = width / height
let ratio = 1
if (this.whRatio > 1 && width > 1024) { // 根据宽高比分情形处理
ratio = 1024 / width
} else if (this.whRatio < 1 && height > 1024) {
ratio = 1024 / height
}
this.imgW = width * ratio // 实际展示图片宽度
this.imgH = height * ratio // 实际展示图片高度
})
页面图片load
方法回调1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37const query = uni.createSelectorQuery()
query.select('#img').boundingClientRect(res => {
const { width, height } = res
this.ratioX = this.imgW / width // 宽度缩放比
this.ratioY = this.imgH / height // 高度缩放比
const { screenWidth } = this.systemInfo // 系统屏幕宽度
this.movableStyle = { // 截取区域相关信息
width, height,
left: (screenWidth - width) / 2,
top: (this.contentHeight - height) / 2
}
this.movableView = { // 截图区域四个角初始坐标
topLeft: {
x: 0,
y: 0
},
topRight: {
x: width - MOVABLE_WIDTH, // MOVABLE_WIDTH 四个角可拖动区域大小
y: 0
},
bottomLeft: {
x: 0,
y: height - MOVABLE_WIDTH
},
bottomRight: {
x: width - MOVABLE_WIDTH,
y: height - MOVABLE_WIDTH
}
}
this.creatCanvas() // 绘图
}).exec()
function creatCanvas() {
const ctx = uni.createCanvasContext('editCanvas')
ctx.drawImage(imgSrc/*图片地址*/, 0, 0, this.imgW, this.imgH)
ctx.draw()
}
导出1
2
3
4
5
6
7
8
9
10
11
12const query = uni.createSelectorQuery()
query.select('#editArea').boundingClientRect(res => {
const { width, height } = res
uni.canvasToTempFilePath({
canvasId: 'editCanvas',
x: this.movableView.topLeft.x * this.ratioX, // 剪裁区域坐标转换
y: this.movableView.topLeft.y * this.ratioY,
width: width * this.ratioX, // 长款转换
height: height * this.ratioY,
fileType: 'png'
})
}).exec()