uni-app uni.canvasToTempFilePath 图片部分机型会出现空白

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

uni-app uni.canvasToTempFilePath 图片部分机型会出现空白

问题描述

调用uni.canvasToTempFilePath截取图片的时候,输出生成的图片是正常的,输出在页面也可以正常显示。但是上传给服务器后,当服务器返回该图片确实空白的。这种情况只在一部分机型的h5端出现,一部分机型正常。出现这种情况的机型的app端也是正常显示的,没有任何问题。只是h5出了问题。

代码示例

ctx.draw(true, () => {  
    var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;  
    var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;  
    var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;  
    var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;  
    uni.canvasToTempFilePath({  
        x: canvasL,  
        y: canvasT,  
        width: canvasW,  
        height: canvasH,  
        destWidth: canvasW,  
        destHeight: canvasH,  
        quality: 0.5,  
        canvasId: 'myCanvas',  
        success: function (res) {  
            uni.hideLoading();  
            let tempFacePath = res.tempFilePath;  
            uni.showLoading({  
                mask: true,  
                title: '上传中...'  
            });  

            uni.uploadFile({  
                url: config.serverUrl + '/user/uploadFace?userId=' + _this.globalUser.id + '&qq=' + config.qq,  
                filePath: tempFacePath,  
                name: 'file',  
                header: {  
                    headerUserId: _this.globalUser.id,  
                    headerUserToken: _this.globalUser.userUniqueToken,  
                    withCredentials: true   
                },  
                success:(res) => {  
                    let resData = JSON.parse(res.data);  
                    if (resData.status == 200) {  
                        var userInfo = resData.data;  
                        uni.setStorageSync('globalUser', userInfo);  
                        uni.hideLoading();  
                        uni.redirectTo({  
                            url: '../settings/settings'  
                        });  
                        uni.navigateBack({  
                            delta: 1  
                        });  

                    } else if (resData.status == 502 || resData.status == 500) {  
                        uni.hideLoading();  
                        uni.showModal({  
                            title: '提示',  
                            content: '当前是异地登录,请重新登录',  
                            showCancel: false,  
                            success: (res) => {  
                                if(res.confirm){  
                                    post('/user/logout',{userId: _this.globalUser.id}).then((res) => {  
                                        if(res.status == 200){  
                                            uni.removeStorageSync("globalUser");  
                                            uni.reLaunch({  
                                                url: '../registerLogin/registerLogin?showToHome=true'  
                                            });  
                                        }  
                                    });                                   
                                }  
                            },  
                            fail: () => {  
                                uni.removeStorageSync("globalUser");  
                                uni.reLaunch({  
                                    url: '../registerLogin/registerLogin?showToHome=true'  
                                });  
                            }  
                        })  
                    }else{  
                        uni.hideLoading();  
                        uni.showToast({  
                            title: resData.msg,  
                            icon: 'none',  
                            image: '/static/icos/error.png',  
                            duration: 3000  
                        });  
                    }  
                },  
                fail: (res) => {  
                    uni.hideLoading();  
                    uni.showModal({  
                        title: '上传失败',  
                        content: res.errMsg,  
                        showCancel: false  
                    });  
                }  
            });  

        }  
    });  
});

52 回复

列出问题机型和使用的浏览器信息


ipad-mini

我也遇到这个问题,怎么样 问题解决了吗

在测试时候,开发者工具和真机调试,微信小程序,还是显示空白啊

解决了吗?两年了。。。IOS真要上还是会空白。。。子组件生成的canvas,咋都获取不到数据

能否详细描述一下

回复 DCloud_UNI_GSQ: 手机是ip6s 系统IOS12,HBX是最新A版,在IOS APP上,创建宽800高1100的CANVAS,所有画的本地图片和网络图片共三张加一些文字都成功了。到了后后一步,draw(true,这里),使用uni.canvastotempfilepath时取出的图片是空白,取不到canvas里正确的图片。而且draw里的回调无效,如果用draw(true,settimeout()…延迟回调有效,但是IOS会提示: canvasToTempFilePath:fail securityerror:the operation is insecure.翻译为什么不安全。。。而且是概率出现非常高,出现后依然无法获取画好的图片。

回复 有问: 绘制的图像分别是哪个?

就是啊,几年了,还没解决啊~~~

回复 DCloud_UNI_GSQ: 一个本地logo.png,一个网络图片.jpg,还有一个JS生成的二维码图片。有人说是大小不能超过800,我改了一下也不管用。我把网络图片JPG下到到本地也不行。我觉得应该是部分机型和系统出现这个问题。但我手上只有IP6S 12.2系统,没办法测试别的。

确实还有问题,请官方人员自行测试:
在ios的QQ和tim中,uni.canvasToTempFilePath 生成的图片是空白(空白是指连尺寸都没有)
但在ios的微信中,又正常。
附件1,是在微信中,正常的;
附件2,是在ios的QQ中,就是空白。
麻烦官方人员测试一下,急需解决。


我的空白是一整张空白图。。。

回复 有问: 我正在排查,好像直接引用又没问题,是uniCloud.uploadFile上传的问题,我还在排查中

回复 风云酷小子: 我根本没有用到上传,就是画了3张图片加了一点文字。安卓都是正常的。

具体说下测试步骤

有办法解决嘛 我搞一下午了!!

唉,一个一个入坑来,就是不见官网人员

巨坑啊,3年了都没解决,还是空白图

具体说下测试步骤

醉了 我还以为我代码写的有问题,排查了两天了,来一搜才发现不止我一个人

能否具体说下测试步骤

回复 DCloud_UNI_GSQ: ios真机白屏问题还没有解决吗,安卓机导出的图片显示正常,但是ios显示的就是白屏

回复 y***@sina.com: 能否具体说下测试步骤

回复 DCloud_UNI_GSQ: 使用图片大小为674KB,尺寸1224X2208时 uni.canvasToTempFilePath返回成功数据为{“errMsg”:“canvasToTempFilePath:ok”,“tempFilePath”:“data:,”},就是data是空的, 当使用小点的图如大小为153KB,尺寸508x761时 data有图片数据。

回复 luojl: 这是bug吗?急啊

回复 luojl: 在h5下iOS真机上出现的

回复 luojl: 你好 问题解决了吗 我被这个bug卡了

有办法解决了吗?uni.canvasToTempFilePath方法写在.draw的回调里面,和需要setTimeOut,都使用了,开发这里一直没复现问题,用户端多次出现ios出现评率较高。

10年都解决不了

回复 全栈OkLin: 啊好烦啊,怎么解决里

ios15.7系统 canvas h5正常生成,ios生成出来白屏,安卓正常显示

使用Safari远程调试看一下,大概率能看到一个跨域相关报错

回复 DCloud_UNI_GSQ: 苹果12 系统为15.5 canvas 在app保存图片报错 “errMsg”: “saveImageToPhotosAlbum:fail [Gallery:-1]未能完成操作。(PHPhotosErrorDomain错误-1。),”, “errCode”: -100, “code”: -100

在苹果11 上面正常保存 小程序正常 H5正常

一样遇到了,求解决办法

回复 DCloud_UNI_GSQ: 是的 ios h5端

一样,h5端ios,求解决办法

你们试试 指定的宽高-1 ctx.draw(true, () => {

    uni.canvasToTempFilePath({    
        canvasId: id,    
        width: width-1,    
        height: height-1,    
        success: (cRes) => {    
            let canvasUrl=cRes.tempFilePath;    
            resolve(canvasUrl);    
        },    
        fail: () => {    
            uni.hideLoading();    
            reject();    
        }    
    })    

}); 看这样是不是就解决ios生成白屏的问题,我是发现白图比我canvas的宽高要大一点点

兄弟你试了吗?能解决问题吗?

我也遇到了这个问题,我感觉是宽度的问题,我只在苹果13和14上有问题,其他都是正常的

回复 9***@qq.com: 哥们你最后解决了吗,我也遇到了,就苹果14以上不行

回复 m***@163.com: 解决了吗

安卓端 通过canvas.drawImage()将要拼接的图片绘制在canvas上,然后在canvas.draw的回调中使用uni.canvasToTempFilePath来生成临时路径,但是生成出来的图片是空的。即使是在回调函数内增加setTimeout来延时也不行,这是怎么回事?uni.createCanvasContext的第二个参数加了this

没有 我也被卡主了

ctx.drawImag(xxxxxx);
ctx.draw(false,function(){
setTimeout(()=>{
uni.canvasToTempFilePath(xxxx)
},200)
}) 在draw的回调函数里,加上settimeout可以解决。

uni.compressImage({ src: src, quality: 30, width: ‘40%’, height:‘40%’, success: res2 => { // 获取图片信息,配置 canvas 尺寸 uni.getImageInfo({ src: res2.tempFilePath, success: res => { // canvas的相关操作 … }, ios环境在压缩图片后就不会出现白色图片问题了,应该是ios对于canvas有限制

这么多年过去了这个bug依旧坚挺

在处理 uni-app 中的 uni.canvasToTempFilePath 方法时,如果在某些机型上遇到图片生成空白的问题,这通常是由于画布内容没有正确渲染或者画布尺寸与图片尺寸不匹配导致的。以下是一些常见的排查和解决方法,并提供相应的代码示例:

1. 确保画布内容已渲染完成

在调用 uni.canvasToTempFilePath 之前,确保画布上的内容已经完全渲染。可以通过在绘制完成后设置一个延时来确保这一点。

uni.canvasToTempFilePath({
    canvasId: 'myCanvas',
    success: function (res) {
        console.log('临时文件路径:', res.tempFilePath);
    },
    fail: function (err) {
        console.error('生成图片失败:', err);
    },
    complete: function () {
        console.log('生成图片完成');
    }
}, 1000); // 延时1秒确保内容渲染完成,注意这不是官方API参数,需自行实现延时逻辑

注意:上述代码中的 1000 毫秒延时是模拟的,实际应使用如 setTimeout 或其他逻辑确保内容渲染。

2. 检查画布尺寸与图片尺寸

确保画布(canvas)的尺寸与要生成的图片尺寸一致。如果尺寸不匹配,可能会导致生成的图片出现空白。

<!-- canvas组件设置宽高 -->
<canvas canvas-id="myCanvas" style="width: 300px; height: 300px;"></canvas>
// 绘制内容到canvas
const ctx = uni.createCanvasContext('myCanvas');
ctx.setFillStyle('red');
ctx.fillRect(0, 0, 300, 300); // 绘制一个红色方块,确保尺寸与canvas一致
ctx.draw(false, () => {
    uni.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success: function (res) {
            console.log('临时文件路径:', res.tempFilePath);
        },
        fail: function (err) {
            console.error('生成图片失败:', err);
        }
    });
});

3. 跨平台兼容性检查

不同平台的canvas实现可能存在差异,建议在不同机型和平台上进行测试,确保兼容性。

4. 清理画布

在每次绘制前,清理画布可以避免一些未知的问题。

const ctx = uni.createCanvasContext('myCanvas');
ctx.clearRect(0, 0, 300, 300); // 清理画布
// 接下来的绘制代码...

通过上述方法,你可以有效地排查和解决 uni.canvasToTempFilePath 在某些机型上生成空白图片的问题。如果问题依旧存在,建议查阅 uni-app 的官方文档或社区,看是否有其他开发者遇到并解决了类似的问题。

回到顶部