吃西瓜的花猫
吃西瓜的花猫
  • 发布:2021-03-10 12:00
  • 更新:2021-03-10 20:41
  • 阅读:471

【报Bug】canvas组件 在H5环境下,效率非常低

分类:uni-app

产品分类: uniapp/H5

PC开发环境操作系统: Mac

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

HBuilderX类型: 正式

HBuilderX版本号: 3.1.4

浏览器平台: Chrome

浏览器版本: 88.0.4324.192

项目创建方式: HBuilderX

示例代码:

uni-方式

drawImageQueue(images, obj, done) {  
        //  
        console.log('打印图片', images);  
        let queue = [];  
        let self = this;  
        let ctx = this.getCanvasContext(obj);  
        let isClear = false;  
        if (typeof (images) === 'string') {  
          images = [images];  
        }  
        for (let img of images) {  
          if (img.length > 0) {  
            queue.push(img);  
          }  
        }  
        let doQueue = function () {  
          let src = null;  
          if (queue.length > 0) {  
            src = queue[0];  
            queue.splice(0, 1);  
            uni.getImageInfo({  
              src: src,  
              success(res) {  
                if (!isClear) {  
                  isClear = true;  
                  ctx.clearRect(0, 0, self.size.width, self.size.height);  
                }  
                ctx.drawImage(res.path, 0, 0, self.size.width, self.size.height)  
                if (queue.length > 0) {  
                  doQueue();  
                } else {  
                  ctx.draw(true,() => {  
                    typeof (done) === 'function' && done.call();  
                  });  
                }  
              },  
              fail(res) {  
                console.error('img fail', src,res);  
                if (queue.length > 0) {  
                  doQueue();  
                } else {  
                  ctx.draw(true,() => {  
                    typeof (done) === 'function' && done.call();  
                  });  
                }  
              }  
            });  
          }  
        }  
        doQueue();  
      },  

使用console.time+console.timeEnd 平均执行时间在200ms以上

原生H5方式

function drawImage(images,done) {  

        console.log('打印图片', images);  
        var queue = [];  
        var isClear = false;  
        if (typeof (images) === 'string') {  
            images = [images];  
        }  
        for (var i = 0;i<images.length;i++) {  
            var img = images[i];  
            if (img.length > 0) {  
                queue.push(img);  
            }  
        }  
        var doQueue = function () {  
            var src = null;  
            if (queue.length > 0) {  
                src = queue[0];  
                queue.splice(0, 1);  
                getImage({  
                    src: src,  
                    success:function(res) {  
                        console.log('res',res)  
                        if (!isClear) {  
                            isClear = true;  
                            ctx.clearRect(0, 0, size.width, size.height);  
                        }  
                        ctx.drawImage(res.path[0], 0, 0, size.width, size.height)  
                        if (queue.length > 0) {  
                            doQueue();  
                        } else {  
                            typeof (done) === 'function' && done.call();  
                        }  
                    },  
                    fail:function(res) {  
                        console.error('img fail', src,res);  
                        if (queue.length > 0) {  
                            doQueue();  
                        } else {  
                            typeof (done) === 'function' && done.call();  
                        }  
                    }  
                });  
            }  
        }  
        doQueue();  
    }  

    function getImage(opt) {  
        var img = new Image(1920,1080);  
        img.src = opt.src;  
        img.onload = opt.success;  
        img.oncompvare = opt.success;  
    }  

//使用console.time+console.timeEnd 平均执行时间在60ms以内

//图片使用同样的地址。使用的本机图片,加载耗时不超过5ms

操作步骤:
drawImageQueue(images, obj, done) {  
        //  
        console.log('打印图片', images);  
        let queue = [];  
        let self = this;  
        let ctx = this.getCanvasContext(obj);  
        let isClear = false;  
        if (typeof (images) === 'string') {  
          images = [images];  
        }  
        for (let img of images) {  
          if (img.length > 0) {  
            queue.push(img);  
          }  
        }  
        let doQueue = function () {  
          let src = null;  
          if (queue.length > 0) {  
            src = queue[0];  
            queue.splice(0, 1);  
            uni.getImageInfo({  
              src: src,  
              success(res) {  
                if (!isClear) {  
                  isClear = true;  
                  ctx.clearRect(0, 0, self.size.width, self.size.height);  
                }  
                ctx.drawImage(res.path, 0, 0, self.size.width, self.size.height)  
                if (queue.length > 0) {  
                  doQueue();  
                } else {  
                  ctx.draw(true,() => {  
                    typeof (done) === 'function' && done.call();  
                  });  
                }  
              },  
              fail(res) {  
                console.error('img fail', src,res);  
                if (queue.length > 0) {  
                  doQueue();  
                } else {  
                  ctx.draw(true,() => {  
                    typeof (done) === 'function' && done.call();  
                  });  
                }  
              }  
            });  
          }  
        }  
        doQueue();  
      },  

预期结果:

实际结果:

bug描述:

绘制多张图片到画布上的过程中,
使用uni-app的 drawImage+draw 相比原生H5中使用drawImage的方式,
执行效率相差非常大

2.这个版本还存在图片base64后如果里面有rpx 或upx 时,会导致base64的值错误。

2021-03-10 12:00 负责人:无 分享
已邀请:
DCloud_UNI_GSQ

DCloud_UNI_GSQ

你是说drawImage使用 base64 的时候包含 rpx 会报错吗?

  • 吃西瓜的花猫 (作者)

    我现在使用的 3.1.4.20210305 还是有这个问题。

    是在从canvas里获取图片转为base64 到外面的image中使用时,如果内容里含有 rpx 还是会导致图片无法显示,

    只能使用img标签来处理。

    image组件 中的img标签是可以显示图片的, 但是同级的div中背景图片无法显示,导致空白

    2021-03-10 22:41

  • DCloud_UNI_GSQ

    回复 吃西瓜的花猫: 这个 base64 能否发一下

    2021-03-11 10:44

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