大肥光光
大肥光光
  • 发布:2020-11-17 09:30
  • 更新:2022-01-14 15:29
  • 阅读:2679

【报Bug】canvas在iOS上使用canvasToTempFilePath导出图片是空白的。所有机型

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: Windows7

HBuilderX类型: 正式

HBuilderX版本号: 2.9.8

手机系统: iOS

手机系统版本号: iOS 13.4

手机厂商: 苹果

手机机型:

页面类型: vue

打包方式: 云端

项目创建方式: HBuilderX

操作步骤:
<template>  
    <view class="">  
        <!-- 当去掉 border: 1px solid #eee; 后导出图片正常  hbuildx 2.9.8 ios iphone4 iphone6 -->  
        <view class="content" style="border: 1px solid #eee;">  
            <canvas style="width: 100%; height: 100%;" id="myCanvas" canvas-id="myCanvas"></canvas>  
        </view>  
        <button type="default" @tap="getPath">点击导出图片(在下方)</button>  
        <image style="width: 750upx;height: 750upx;" :src="canvasPath" mode=""></image>  
    </view>  
</template>  

<script>  
    let context = null;  
    export default {  
        data() {  
            return {  
                canvasPath: ""  
            }  
        },  
        onLoad() {  
            this.$nextTick(() => {  
                this.setContext();  
            })  
        },  
        methods: {  
            setContext() {  
                context = uni.createCanvasContext('myCanvas', this);  
                context.setStrokeStyle(this.lColor);  
                //设置线的宽度  
                context.setLineWidth(5);  
                this.drawLine(0,0,300, 300);  
                this.drawLine(300,0,0, 300);  
            },  
            drawLine(startX, startY,x, y) {  
                context.moveTo(startX, startY);  
                context.lineTo(x, y)  
                context.stroke();  
                context.draw(true);  
            },  
            getPath() {  
                const query = uni.createSelectorQuery().in(this);  
                let _this = this;  
                query.select('.content').boundingClientRect(data => {  
                    uni.canvasToTempFilePath({  
                        x: data.left,  
                        y: data.top,  
                        width: data.width,  
                        height: data.height,  
                        destWidth: data.width,  
                        destHeight: data.height,  
                        canvasId: 'myCanvas',  
                        success: (res) => {  
                            console.log('signNamePg======================================', res.tempFilePath)  
                            this.canvasPath = res.tempFilePath;  
                        }  
                    }, this)  
                }).exec();  
            }  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
        width: 750upx;  
        height: 650upx;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>

预期结果:

<!-- 当去掉 border: 1px solid #eee; 后导出图片正常 hbuildx 2.9.8 ios iphone4 iphone6 -->

实际结果:

<!-- 当去掉 border: 1px solid #eee; 后导出图片正常 hbuildx 2.9.8 ios iphone4 iphone6 -->

bug描述:

<template>  
    <view class="">  
        <!-- 当去掉 border: 1px solid #eee; 后导出图片正常  hbuildx 2.9.8 ios iphone4 iphone6 -->  
        <view class="content" style="border: 1px solid #eee;">  
            <canvas style="width: 100%; height: 100%;" id="myCanvas" canvas-id="myCanvas"></canvas>  
        </view>  
        <button type="default" @tap="getPath">点击导出图片(在下方)</button>  
        <image style="width: 750upx;height: 750upx;" :src="canvasPath" mode=""></image>  
    </view>  
</template>  

<script>  
    let context = null;  
    export default {  
        data() {  
            return {  
                canvasPath: ""  
            }  
        },  
        onLoad() {  
            this.$nextTick(() => {  
                this.setContext();  
            })  
        },  
        methods: {  
            setContext() {  
                context = uni.createCanvasContext('myCanvas', this);  
                context.setStrokeStyle(this.lColor);  
                //设置线的宽度  
                context.setLineWidth(5);  
                this.drawLine(0,0,300, 300);  
                this.drawLine(300,0,0, 300);  
            },  
            drawLine(startX, startY,x, y) {  
                context.moveTo(startX, startY);  
                context.lineTo(x, y)  
                context.stroke();  
                context.draw(true);  
            },  
            getPath() {  
                const query = uni.createSelectorQuery().in(this);  
                let _this = this;  
                query.select('.content').boundingClientRect(data => {  
                    uni.canvasToTempFilePath({  
                        x: data.left,  
                        y: data.top,  
                        width: data.width,  
                        height: data.height,  
                        destWidth: data.width,  
                        destHeight: data.height,  
                        canvasId: 'myCanvas',  
                        success: (res) => {  
                            console.log('signNamePg======================================', res.tempFilePath)  
                            this.canvasPath = res.tempFilePath;  
                        }  
                    }, this)  
                }).exec();  
            }  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
        width: 750upx;  
        height: 650upx;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>  
2020-11-17 09:30 负责人:无 分享
已邀请:
chenli

chenli

提供个可复现简单工程示例,方便他人排查问题!

  • 大肥光光 (作者)

    直接在canvas上的内容 使用 uni.canvasToTempFilePath 在ios真机或者云打包出来就能重现,hbuildx2.6.16 能导出 更新到2.9.8导出的图片就是空白的。已经说的很清楚了。我们已经切换来重现的问题,百分百出现。


    15 秒前

    2020-11-17 09:58

  • chenli

    回复 大肥光光: 有自己创建简单工程来重现问题吗?

    2020-11-17 10:10

  • chenli

    回复 大肥光光: 帮你在hx2.9.8+,使用hello uni-app模块示例没有重现你的问题。

    2020-11-17 10:13

  • 大肥光光 (作者)

    回复 chenli: 请问,你是ios真机调试吗?你的基座是最新的基座吗?一样的代码,安卓可以,2.6.16的版本ios可以,切换到2.9.8,安卓可以,ios不可以。这不是框架上出了问题?上面已经贴出示例,它的入口是一个按钮事件而已。

    2020-11-17 10:26

  • DCloud_UNI_GSQ

    回复 大肥光光: 试试 2.9.9 alpha 是否正常,如果仍然有问题,提供一个能复现问题的示例工程。绝对不是你说的那样不清楚就可以复现的。

    2020-11-17 13:06

  • DCloud_UNI_GSQ

    你反馈导出空白,你也没提及绘制了什么内容。

    2020-11-17 13:07

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 这样描述够详细吗?可以继续沟通,希望uni能够解决。谢谢。具体hbuildx版本是:当使用2.6.16(非v3编译器)时,不会有这样的问题。当使用2.6.16(启用v3编译器)以及使用2.9.8+版本时(预计2.6.16以后的版本均有这样的问题)出现问题

    2020-11-20 11:29

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 通过进一步的测试,给canvas容器加上一些样式如:border: 1px solid #ddd; 也会导致canvasToTempFilePath 在ios中出现导出空白图片效果。这种应该是严重问题,请仔细检查这种问题会不会引起其他问题吧。

    2020-11-20 14:42

  • DCloud_UNI_GSQ

    回复 大肥光光: 提供一下完整的测试工程以及操作步骤

    2020-11-23 19:17

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 已经提供最简单示例工程,直接复制代码即可运行。点击 “点击导出图片(在下方)” 按钮看到下方的图片是空白的。去掉 border: 1px solid #eee; 再点击 “点击导出图片(在下方)” 按钮 即可看到下方导出图片正常,代码中有注释。

    2020-11-25 12:09

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 已在操作步骤和bug描述中粘贴上简单示例,直接复制就可。

    2020-11-25 12:10

  • DCloud_UNI_GSQ

    回复 大肥光光: 麻烦上传一下完整的测试工程啊

    2020-11-30 10:53

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 已经在bug描述里面上传完成整个最简单的工程附件 zip,用hbuildx2.9.8 打基座运行到ios真机上。我上面给的代码竟然不够你们测试?我已经不知道要上传到什么样程度的测试工程了。

    2020-11-30 17:49

DCloud_UNI_GSQ

DCloud_UNI_GSQ

附件已收到,排查完毕
原因:使用方式有误, 导致iOS设备和安卓设备的差异显现
差异详情:
iOS获取内容大小超过画布大小时,获取内容为空白
.content为canvas外层元素大小,有1px的边框,比canvas大2像素,减去这两像素后测试正常。
修改建议:
获取canvas的大小,不要用其他元素的大小来替代。另外x、y、width、height、destWidth、destHeight均可缺省。

query.select('.content').boundingClientRect(data => {  
                    console.log(data)  
                    uni.canvasToTempFilePath({  
                        x: data.left,//这里这样写是错的,x是相对于canvas的坐标不是相对于窗口的  
                        y: data.top,//这里这样写是错的,y是相对于canvas的坐标不是相对于窗口的  
                        width: data.width-2,//这里这样写是错的,width是要获取的内容宽度不是其他元素的宽度  
                        height: data.height-2,  
                        destWidth: data.width-2,  
                        destHeight: data.height-2,  
                        canvasId: 'myCanvas',  
                        success: (res) => {  
                            console.log('signNamePg======================================', res.tempFilePath)  
                            this.canvasPath = res.tempFilePath;  
                        }  
                    }, this)  
                }).exec();

针对iOS和安卓的以上差异,后续会在框架内进行处理

  • 大肥光光 (作者)

    关于x y width height 本意是我想在项目中是设置canvas尺寸与容器尺寸一致的,并且是取容器相对位置的(最终获取canvas的位置及尺寸,当时忘了为什么不直接拿canvas的数据,不知道是拿不到还是怎么了)。以上的x y获取的位置不是窗口的,是容器的位置,其实就是canvas的位置。感谢解答疑惑,原来是取的大于canvas的原因。

    2020-12-02 17:46

  • DCloud_UNI_GSQ

    回复 大肥光光: xy不是传入canvas的位置,如果需要从左上角默认或者传入0即可,xy始终是相对于canvas左上角。

    2020-12-02 17:52

  • 大肥光光 (作者)

    回复 DCloud_UNI_GSQ: 去重新看了下文档,看来是我理解有偏差了。感谢指出问题。

    2020-12-02 18:11

DCloud_UNI_GSQ

DCloud_UNI_GSQ

HBuilderX 3.1.0 alpha 已修复

  • N***@163.com

    修复之后出现的问题是:如果传入 height 值,则生成的图片 height最多只能和 width 相等(正方形)。用过往版本生成是正常的。

    2021-02-21 14:27

  • DCloud_UNI_GSQ

    回复 N***@163.com: 更新到 3.1.3 alpha

    2021-02-22 10:55

1***@qq.com

1***@qq.com - 博客礼

更新到 3.1.3 alpha 云打包,生成的图片也还是个正方形。。。有一样问题的吗?

  • DCloud_UNI_GSQ

    打包之前(使用基座预览)是否正常

    2021-02-24 15:54

  • 1***@qq.com

    回复 DCloud_UNI_GSQ: 用离线sdk打的不行,换成云打包的可以了,只试了andorid的,我去测测ios的。。。不过android11 分享还不行,微信好友、朋友圈拉不起,QQ拉起提示分享成功,但是二次提示没有文件

    2021-02-24 16:20

  • DCloud_UNI_GSQ

    回复 1***@qq.com: 离线的 sdk 是不是没更新

    2021-02-24 19:57

  • DCloud_UNI_GSQ

    分享问题单独发帖反馈

    2021-02-24 19:58

有问

有问 - 生活,趣与失。

解决了吗?我安卓正常,iOS也是获取一直空白。。。哎。

该问题目前已经被锁定, 无法添加新回复