uni-app vue3创建 canvas 画布,保存到相册报错

发布于 1周前 作者 gougou168 来自 Uni-App

uni-app vue3创建 canvas 画布,保存到相册报错

测试过的手机:

mate60

示例代码:

<template>  
    <view>  
        <canvas style="width: 300px; height: 400px;"  
            canvas-id="firstCanvas" id="firstCanvas"></canvas>  

        <button @click="saveImage11">保存</button>  
    </view>  

</template>  

<script>  
    export default {  
        data() {  
            return {  
                selectId: 'firstCanvas',  
                scrollLeft: 0,  
                canvas: null  
            }  
        },  
        props: ['content'],  
        watch: {  
            content(value) {  
                if (value) {  
                    this.createCanvas11()  
                }  
            }  
        },  
        methods: {  
            // 生成canvas  
            createCanvas11() {  
                const ctx = uni.createCanvasContext('firstCanvas', this);  
                ctx.clearRect(0, 0, 300, 400)  
                ctx.fillStyle = "#FFFFFF";  
                ctx.fillRect(0, 0, 300, 400);  

                function findBreakPoint(text, width, context) {  
                    var min = 0;  
                    var max = text.length - 1;  
                    while (min <= max) {  
                        var middle = Math.floor((min + max) / 2);  
                        var middleWidth = context.measureText(text.substr(0, middle)).width;  
                        var oneCharWiderThanMiddleWidth = context.measureText(text.substr(0, middle + 1)).width;  
                        if (middleWidth <= width && oneCharWiderThanMiddleWidth > width) {  
                            return middle;  
                        }  
                        if (middleWidth < width) {  
                            min = middle + 1;  
                        } else {  
                            max = middle - 1;  
                        }  
                    }  
                    return -1;  
                }  

                function breakLinesForCanvas(text, width, font) {  
                    var result = [];  
                    var breakPoint = 0;  
                    if (font) {  
                        ctx.font = font;  
                    }  
                    while ((breakPoint = findBreakPoint(text, width, ctx)) !== -1) {  
                        result.push(text.substr(0, breakPoint));  
                        text = text.substr(breakPoint);  
                    }  
                    if (text) {  
                        result.push(text);  
                    }  
                    return result;  
                }  
                ctx.strokeRect(5, 5, 292, 392)  
                ctx.setFillStyle('black')  
                const content = breakLinesForCanvas(this.content, 260, '28px 微软雅黑');  
                content.forEach(function(line, index) {  
                    ctx.fillText(line, 20, 30 * index + 50);  
                });  
                ctx.drawImage("/static/er.jpg", 20, 260, 100, 100);  
                let wordsList = [  
                    '长按识别二维码',  
                    '一天一句毒鸡汤',  
                    '每天一碗,人生耀眼'  
                ]  
                ctx.setFontSize(14)  
                ctx.fillText(wordsList[0], 25, 380);  
                ctx.setFontSize(18)  
                ctx.fillText(wordsList[1], 140, 310);  
                ctx.setFontSize(16)  
                ctx.fillText(wordsList[2], 130, 340);  
                this.canvas = ctx  
                ctx.draw()  
            },  

            // 保存到相册  
            saveImage11() {  
                let that = this;  
                wx.canvasToTempFilePath({  
                    x: 0,  
                    y: 0,  
                    width: 300,  
                    height: 400,  
                    destWidth: 900,  
                    destHeight: 1200,  
                    // fileType: 'jpg',  
                    // quality: 1,  
                    canvasId: 'firstCanvas',  
                    canvas: this.canvas,  
                    success: function(res) {  
                        wx.saveImageToPhotosAlbum({  
                            filePath: res.tempFilePath,  
                            success() {  
                                that.canvasFlag = false  
                                that.$refs.shareBox.close();  
                                uni.showToast({  
                                    title: '保存成功!',  
                                    duration: 2000  
                                });  
                            }  
                        })  
                    },  
                    fail: function ( res ) {  
                        console.log(res)  
                    }  
                })  
            }  

        }  
    }  
</script>

操作步骤:

这段代码用的是 vue2 语法,运行环境为 vue3,canvas 能正常加载,但是保存 canvas 到临时目录报错。

预期结果:

正常保存

实际结果:

报错


1 回复

在使用 uni-app 和 Vue 3 创建 canvas 画布并保存到相册时,可能会遇到一些常见问题。以下是一些可能的原因和解决方案:

1. Canvas 绘制内容未完成

  • 问题: 在保存 canvas 内容之前,可能 canvas 的绘制还没有完成。
  • 解决方案: 确保在保存之前,canvas 的绘制已经完成。可以使用 setTimeout 或者 Promise 来确保绘制完成后再进行保存。
// 假设 canvasId 是你的 canvas 组件的 id
const canvas = uni.createCanvasContext('canvasId');
canvas.draw(); // 绘制内容
canvas.draw(false, () => {
    // 绘制完成后保存
    uni.canvasToTempFilePath({
        canvasId: 'canvasId',
        success: (res) => {
            const tempFilePath = res.tempFilePath;
            uni.saveImageToPhotosAlbum({
                filePath: tempFilePath,
                success: () => {
                    console.log('保存成功');
                },
                fail: (err) => {
                    console.error('保存失败', err);
                }
            });
        },
        fail: (err) => {
            console.error('生成临时文件失败', err);
        }
    });
});

2. 权限问题

  • 问题: 保存到相册需要用户授权,如果没有授权,保存操作会失败。
  • 解决方案: 在保存之前,先检查并请求相册权限。
uni.getSetting({
    success(res) {
        if (!res.authSetting['scope.writePhotosAlbum']) {
            uni.authorize({
                scope: 'scope.writePhotosAlbum',
                success() {
                    // 用户授权成功,继续保存操作
                },
                fail() {
                    console.error('用户拒绝授权');
                }
            });
        } else {
            // 已有权限,继续保存操作
        }
    }
});

3. Canvas 尺寸问题

  • 问题: 如果 canvas 的尺寸过大或过小,可能会导致保存失败。
  • 解决方案: 确保 canvas 的尺寸合理,并且在保存时指定正确的宽度和高度。
uni.canvasToTempFilePath({
    canvasId: 'canvasId',
    width: 300, // 指定宽度
    height: 300, // 指定高度
    success: (res) => {
        const tempFilePath = res.tempFilePath;
        uni.saveImageToPhotosAlbum({
            filePath: tempFilePath,
            success: () => {
                console.log('保存成功');
            },
            fail: (err) => {
                console.error('保存失败', err);
            }
        });
    },
    fail: (err) => {
        console.error('生成临时文件失败', err);
    }
});
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!