h***@126.com
h***@126.com
  • 发布:2024-10-24 13:20
  • 更新:2024-10-24 17:21
  • 阅读:274

uni.canvasToTempFilePath方法在ios app移动端报错

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: windows 10企业版

HBuilderX类型: 正式

HBuilderX版本号: 4.29

手机系统: iOS

手机系统版本号: iOS 16

手机厂商: 苹果

手机机型: 8plus

页面类型: vue

vue版本: vue2

打包方式: 云端

项目创建方式: HBuilderX

操作步骤:

                                            canvasId: 'watermarkCanvas',  
                                            success: (res) => {  
                                                console.log("res",res);  
                                                resolve(res.tempFilePath);  
                                            },  
                                            fail: (err) => {  
                                                console.log("err11",err);  
                                                reject(err);  
                                            }  
                                        }); ```

预期结果:

在 ios app端返回图片临时路径

实际结果:

报错 "errMsg": "canvasToTempFilePath:fail SecurityError: The operation is insecure."

bug描述:

hbuilderx 4.29最新版本,uni.canvasToTempFilePath方法在ios app移动端报错 "errMsg": "canvasToTempFilePath:fail SecurityError: The operation is insecure.",安卓手机端可以正常传图片

2024-10-24 13:20 负责人:DCloud_UNI_OttoJi 分享
已邀请:
DCloud_UNI_OttoJi

DCloud_UNI_OttoJi - 日常回复 uni-app/x 问题,如果艾特我没看到,请主动私信

我使用下面 demo 运行到 vue2 + ios 真机、模拟器上未报错

<template>  
    <view>  

        <view>canvas to temp file path</view>  
        <canvas style="width: 300px; height: 200px;border: 1px solid red;" id="myCanvas" canvas-id="myCanvas"></canvas>  
        <button @click='generateImage'>generate file</button>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
            }  
        },  
        methods: {  
            drawCanvas() {  
                var ctx = uni.createCanvasContext('myCanvas')  
                // begin path  
                ctx.rect(10, 10, 100, 30)  
                ctx.setFillStyle('yellow')  
                ctx.fill()  

                // begin another path  
                ctx.beginPath()  
                ctx.rect(10, 40, 100, 30)  

                // only fill this rect, not in current path  
                ctx.setFillStyle('blue')  
                ctx.fillRect(10, 70, 100, 30)  

                ctx.rect(10, 100, 100, 30)  

                // it will fill current path  
                ctx.setFillStyle('red')  
                ctx.fill()  
                ctx.draw(true, () => {  
                    this.generateImage()  
                })  
            },  
            generateImage() {  
                uni.canvasToTempFilePath({  
                    x: 100,  
                    y: 200,  
                    width: 50,  
                    height: 50,  
                    destWidth: 100,  
                    destHeight: 100,  
                    canvasId: 'myCanvas',  
                    success: (res)=> {  
                        // 在H5平台下,tempFilePath 为 base64  
                        console.log(res)  
                    },  
                    fail(res) {  
                        console.log('error', res)  
                    }  
                })  
            }  
        },  
        onReady() {  
            this.drawCanvas()  
        }  
    }  
</script>  

<style>  
</style>
  • h***@126.com (作者)

    找到问题是ctx.drawImage()引起的,注掉就返回路径了,但是需要用到这个方法怎么办啊

    2024-10-24 15:28

  • DCloud_UNI_OttoJi

    回复 h***@126.com: 像我一样提供你到基础代码,说明你是怎么写的,是引入三方图片画布被污染吗

    2024-10-24 16:51

  • h***@126.com (作者)

    回复 DCloud_UNI_OttoJi:我的写法是下面那条

    2024-10-25 10:07

h***@126.com

h***@126.com (作者)

addWatermark(data) {  
                return new Promise((resolve, reject) => {  
                    uni.getImageInfo({  
                        src: data.url,  
                        success: (info) => {  
                                                 console.log('info', info);  
                            setTimeout(() => {  

                                    console.log('info.width, info.height', info.width, info.height);  
                                    const ctx = uni.createCanvasContext('watermarkCanvas');  
                                    ctx.beginPath()  

                                    ctx.drawImage(info.path, 0, 0, info.width, info.height);  

                                    ctx.width = info.width / 2;  
                                    ctx.height = info.height / 2;  

                                    // 设置水印 文本换行  
                                        const breakTextLines = (markDept, maxWidth) => {  
                                        const words = markDept.split('');  
                                        let line = '';  
                                        const lines = [];  
                                        for (let i = 0; i < words.length; i++) {  
                                            const word = words[i];  
                                            const testLine = line + word;  
                                            const metrics = ctx.measureText(testLine);  

                                            if (metrics.width > maxWidth && i > 0) {  
                                                lines.push(line);  
                                                line = word;  
                                            } else {  
                                                line = testLine;  
                                            }  
                                        }  
                                        lines.push(line);  

                                        return lines;  
                                    };  

                                    if (data.markShow) {  
                                        // 设置水印样式  
                                        ctx.setFontSize(20); // 设置字体大小  
                                        ctx.setFillStyle('white'); // 设置水印颜色  
                                        ctx.setGlobalAlpha(0.7); // 设置水印透明度  

                                        // 动态添加水印  
                                        let yPosition = 100;  
                                        data.listItem.forEach((item,index) => {  
                                            // 只有当 status 为 true 时才绘制水印  
                                            if (item.status !== false) {  
                                                if(index == 1){//定位的水印  
                                                    ctx.fillText(item.key, 30, yPosition); // 设置水印位置  
                                                    yPosition += 20;  

                                                    const lines = breakTextLines(item.value, 200);  
                                                    const linesLength = lines.length;  
                                                    lines.forEach((line, index) => {  
                                                        ctx.fillText(line, 30, (index * 20 + yPosition))  
                                                    })  
                                                    yPosition += 100; // 为下一组水印留出空间  

                                                }else{  
                                                    ctx.fillText(item.key, 30, yPosition);  
                                                    yPosition += 20;  
                                                    ctx.fillText(item.value, 30, yPosition);  
                                                    yPosition += 40; // 为下一组水印留出空间  
                                                }  

                                            }  
                                        });  
                                    }  
                                    ctx.fill()   
                                    console.log("aaaaaaaaaaaaaaaaaaaa",ctx);  

                                    ctx.draw(true, () => {  
                                        // this.generateImage()  
                                        uni.canvasToTempFilePath({  
                                            canvasId: 'watermarkCanvas',  
                                            success: (res) => {  
                                                console.log("res",res);  
                                                resolve(res.tempFilePath);  
                                            },  
                                            fail: (err) => {  
                                                console.log("err11",err);  
                                                reject(err);  
                                            }  
                                        });  
                                    });  

                            },300)  
                        },  
                        fail: (err) => {  
                            console.log("err",err);  
                            reject(err);  
                        }  
                    });  
                });  
            },

ios app 用this.livePusher.snapshot 拍照后 uni.getImageInfo返回的info

{  
    "height": 384,  
    "orientation": "up",  
    "path": "file:///var/mobile/Containers/Data/Application/139421CD-C332-4D5D-8C19-6D5BEEE4FBFC/Documents/Pandora/apps/EC2B81D49F96C6F0B82075DFEA627006/doc/uniapp_temp_1729761123932/compressed/1729761218126_2024-10-24%2017:13:38.jpg",  
    "type": "jpeg",  
    "width": 288,  
    "errMsg": "getImageInfo:ok"  
}

这个方法中去掉 ctx.drawImage, ios app就能正常生成本地文件路径

  • 蔡cai

    加个这个试下const ctx = uni.createCanvasContext('watermarkCanvas', this);

    2024-10-24 17:57

  • h***@126.com (作者)

    回复 蔡cai: 加了后还是报错,"errMsg": "canvasToTempFilePath:fail SecurityError: The operation is insecure."

    2024-10-24 18:13

  • 蔡cai

    回复 h***@126.com: 没报过这个错,要不你降下hbuilderx版本或者升级版本看看

    2024-10-24 18:34

  • h***@126.com (作者)

    回复 蔡cai: 这个就是刚从低版升到最新版的

    2024-10-24 18:43

  • DCloud_UNI_OttoJi

    回复 h***@126.com: 这个报错,在 ask 社区搜一下,比如 https://ask.dcloud.net.cn/article/41016

    2024-10-25 11:12

  • x***@qq.com

    可以使用uni.saveFile将图片保存到本地,然后使用保存后的图片地址。就可以l

    2024-12-19 13:18

要回复问题请先登录注册