uni-app canvasToTempFilePath:fail Failed to execute
uni-app canvasToTempFilePath:fail Failed to execute
项目属性 | 值 |
---|---|
产品分类 | uniapp/小程序/微信 |
PC开发环境操作系统 | Mac |
PC开发环境操作系统版本号 | 12.6.2 |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 4.07 |
第三方开发者工具版本号 | Stable Build 1.06.2402040 |
基础库版本号 | 3.3.5 |
项目创建方式 | HBuilderX |
示例代码:
<template>
<view class="c-display-flex-V-center my-page-container" @click="downloadImg">
<canvas type="2d" id="myCanvas" class="my-page-canvas" />
</view>
</template>
<script>
const ctxW = 280;
const ctxH = 275;
export default {
name: 'invitation',
components: {
myGridItem,
},
data() {
return {
canvasObject: undefined,
};
},
beforeCreate() {
console.log('beforeCreate enter');
},
created() {
console.log('created enter');
},
mounted() {
console.log('mounted enter');
},
onLoad(option) {
console.log('onLoad');
},
onReady() {
this.drawCanvas();
},
methods: {
drawCanvas() {
const query = uni.createSelectorQuery().in(this);
let _this = this;
query.select("#myCanvas")
.fields({
node: true,
size: true,
})
.exec(async (res) => {
_this.canvasObject = res[0].node.id;
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
let offsetY = 15;
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = ctxW * dpr;
canvas.height = ctxH * dpr;
ctx.scale(dpr, dpr);
let _offsetY = offsetY;
const imageSrc = '../../static/images/invitation_head.png';
let image = canvas.createImage();
await new Promise(resolve => {
image.onload = resolve;
image.src = imageSrc;
});
ctx.drawImage(image, (ctxW - 250) / 2, _offsetY, 250, 35);
offsetY += (35 + 10);
ctx.fillStyle = '#f3f3f3';
ctx.fillRect((ctxW - 200) / 2, offsetY, 200, 200);
});
},
downloadImg() {
uni.showLoading({
title: '正在下载...',
});
uni.canvasToTempFilePath({
canvas: this.canvasObject,
x: 0,
y: 0,
width: ctxW,
height: ctxH,
destWidth: ctxW,
destHeight: ctxH,
quality: 1.0,
success: function(res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function(saveRes) {
uni.showToast({
title: '保存成功',
});
},
fail: function(saveErr) {
if (saveErr.errMsg === 'saveImageToPhotosAlbum:fail:auth denied' ||
saveErr.errMsg === 'saveImageToPhotosAlbum:fail auth deny' ||
saveErr.errMsg === 'saveImageToPhotosAlbum:fail authorize no response'
) {
uni.showModal({
title: '需要您授权保存相册',
modalType: false,
success: modalRes => {
uni.openSetting({
success(settingRes) {
if (settingRes.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '温馨提醒',
content: '获取权限成功,再次点击保存即可~',
modalType: false,
})
} else {
wx.showModal({
title: '温馨提醒',
content: '获取权限失败,将无法保存到相册哦~',
modalType: false,
})
}
},
fail(settingError) {
console.log('settingError', JSON.stringify(settingError));
},
});
},
});
}
},
});
},
fail: function(err) {
uni.showToast({
title: '生成图片失败',
});
},
}, this);
},
},
}
</script>
<style scoped>
.my-page-container {
background-color: white;
height: 500px;
}
.my-page-canvas {
width: 280px;
height: 275px;
}
.my-page-canvas-core {
box-sizing: border-box;
width: 280px;
height: 275px;
padding: 15px;
display: flex;
flex-direction: column;
align-items: center;
}
.core-head-image {
width: 250px;
height: 35px;
}
.core-content-image {
margin-top: 10px;
width: 200px;
height: 200px;
background-color: #f3f3f3;
}
</style>
操作步骤:
- 点击图片区域,即可触发下载任务。
预期结果:
- 能够生成图片并保存到相册中。
实际结果:
- 生成图片失败。
bug描述:
- Canvas绘制并生成图片失败,报错信息如下:
{"errMsg":"canvasToTempFilePath:fail Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas or VideoFrame)'"}
4 回复
小程序把 type="2d"去掉就好了
把 type="2d"去掉,使用createCanvasContext绘制画面的图片很模糊。
已解决。canvas在下载的时候再先使用createSelectorQuery查找到,而不是使用之前查找的对象。参考链接 https://developers.weixin.qq.com/community/develop/article/doc/000242073903a04e082ab595b52013 。
在 uni-app 中,canvasToTempFilePath
是一个用于将 canvas 内容导出为图片路径的 API。如果你遇到 canvasToTempFilePath:fail Failed to execute
的错误,可能是由于以下原因之一:
1. Canvas 未正确渲染
- 原因: 在调用
canvasToTempFilePath
时,Canvas 可能还没有完成渲染,导致导出失败。 - 解决方案: 确保在 Canvas 渲染完成后再调用
canvasToTempFilePath
。可以使用setTimeout
延迟调用,或者在 Canvas 的draw
方法完成后再执行导出。
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
console.log(res.tempFilePath);
},
fail: (err) => {
console.error(err);
}
});
}, 500); // 延迟 500ms 确保 Canvas 渲染完成
2. Canvas ID 错误
- 原因:
canvasId
参数传递错误,无法找到对应的 Canvas 元素。 - 解决方案: 确保
canvasId
与 Canvas 元素的canvas-id
属性一致。
<canvas canvas-id="myCanvas" style="width: 300px; height: 300px;"></canvas>
uni.canvasToTempFilePath({
canvasId: 'myCanvas', // 确保与 canvas-id 一致
success: (res) => {
console.log(res.tempFilePath);
},
fail: (err) => {
console.error(err);
}
});
3. Canvas 尺寸问题
- 原因: Canvas 的宽度或高度为 0,导致无法导出图片。
- 解决方案: 确保 Canvas 的宽度和高度设置正确,并且不为 0。
<canvas canvas-id="myCanvas" style="width: 300px; height: 300px;"></canvas>
4. 未在 draw
方法中绘制内容
- 原因: 如果没有在 Canvas 上绘制任何内容,导出时会失败。
- 解决方案: 确保在调用
canvasToTempFilePath
之前,已经在 Canvas 上绘制了内容。
const ctx = uni.createCanvasContext('myCanvas');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 100);
ctx.draw();
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
console.log(res.tempFilePath);
},
fail: (err) => {
console.error(err);
}
});
}, 500);
5. 平台兼容性问题
- 原因: 在某些平台(如小程序)上,
canvasToTempFilePath
的实现可能有所不同,导致导出失败。 - 解决方案: 确保在目标平台上测试代码,并根据平台文档调整代码。
6. 权限问题
- 原因: 在某些平台上,导出 Canvas 内容可能需要特定的权限或配置。
- 解决方案: 检查目标平台的文档,确保已正确配置权限。
7. Canvas 上下文未完成绘制
- 原因: 如果在
ctx.draw()
之后立即调用canvasToTempFilePath
,可能会导致 Canvas 内容尚未完全绘制。 - 解决方案: 使用
ctx.draw
的callback
参数,确保在绘制完成后再调用canvasToTempFilePath
。
const ctx = uni.createCanvasContext('myCanvas');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 100);
ctx.draw(true, () => {
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
console.log(res.tempFilePath);
},
fail: (err) => {
console.error(err);
}
});
});