BugEngineer
BugEngineer
  • 发布:2022-09-04 23:19
  • 更新:2022-09-05 14:26
  • 阅读:1260

【报Bug】canvas 中 使用 image.onload 偶尔不执行

分类:uni-app

产品分类: uniapp/H5

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 3.5.3

浏览器平台: Chrome

浏览器版本: 79.0.3945.117

项目创建方式: HBuilderX

操作步骤:

使用canvas拼接图片(共两张图片)
// 第一张图片
let image = document.createElement("img");
image.setAttribute('crossOrigin', 'anonymous');
image.src = url
image.onload = () => {}
// 第二张图片
let imageCode = document.createElement("img");
imageCode.setAttribute('crossOrigin', 'anonymous');
imageCode.src = qrCode
imageCode .onload = () => {}

第二张图片 imageCode .onload方法偶尔不执行

预期结果:

使用canvas拼接图片(共两张图片)
// 第一张图片
let image = document.createElement("img");
image.setAttribute('crossOrigin', 'anonymous');
image.src = url
image.onload = () => {}
// 第二张图片
let imageCode = document.createElement("img");
imageCode.setAttribute('crossOrigin', 'anonymous');
imageCode.src = qrCode
imageCode .onload = () => {}

第二张图片 imageCode .onload方法偶尔不执行

实际结果:

使用canvas拼接图片(共两张图片)
// 第一张图片
let image = document.createElement("img");
image.setAttribute('crossOrigin', 'anonymous');
image.src = url
image.onload = () => {}
// 第二张图片
let imageCode = document.createElement("img");
imageCode.setAttribute('crossOrigin', 'anonymous');
imageCode.src = qrCode
imageCode .onload = () => {}

第二张图片 imageCode .onload方法偶尔不执行

bug描述:

使用canvas拼接图片(共两张图片)
// 第一张图片
let image = document.createElement("img");
image.setAttribute('crossOrigin', 'anonymous');
image.src = url
image.onload = () => {}
// 第二张图片
let imageCode = document.createElement("img");
imageCode.setAttribute('crossOrigin', 'anonymous');
imageCode.src = qrCode
imageCode .onload = () => {}

第二张图片 imageCode .onload方法偶尔不执行

2022-09-04 23:19 负责人:无 分享
已邀请:
CODE_XU

CODE_XU

可以把 图片地址 发出来吗?有没有可能是图片地址的问题

  • BugEngineer (作者)

    http://117.78.35.40:9000/coulee/2022/07/14/740cd2269421414ca42c6b7be93d3cf5.jpg


    我们的需求是显示后端返回的二维码生成海报,我试过来自不同域的图片,也是偶尔出来偶尔不出来。IOS和MAC系统不执行的概率更大,感谢您的回复 麻烦您看下呢

    2022-09-05 11:09

  • BugEngineer (作者)

    您好,我把关键代码贴到回复中了,其中第一个onload每次都执行,第二个就偶尔出不来

    2022-09-05 11:12

BugEngineer

BugEngineer (作者)

let image = document.createElement("img");
image.setAttribute('crossOrigin', 'anonymous');
image.src = url

let imageCode = document.createElement("img");  
imageCode.setAttribute('crossOrigin', 'anonymous');  
imageCode.src = qrCode  

var canvas = document.createElement("canvas");  
var context = canvas.getContext('2d');  
image.onload = () => {  
    canvas.width = image.width;  
    canvas.height = image.height; //图片大小不同导致不一样 是否可以要求上传的尺寸是相同的  
    console.log('宽高', canvas.width, canvas.height)  
    context.fillStyle = "#fff"; // 解决透明背景变为黑色问题  
    context.fillRect(0, 0, canvas.width, canvas.height);  
    context.drawImage(image, 0, 0, image.width, image.height);  
    context.font = '50px "微软雅黑"'; //设置字体  
    context.fillStyle = "rgba(51,51,51,0.7)";  
    imageCode.onload = () => {  
        // 后边的逻辑 经常不执行  换了图片也不行  
    }
  • CODE_XU

    http://117.78.35.40:9000/coulee/2022/07/14/740cd2269421414ca42c6b7be93d3cf5.jpg 这个是第一个的地址吗?

    偶尔出不来的是 qrCode 是吗?

    出不来的时候你看一下 qrCode 链接,是不是可以访问到二维码图片

    2022-09-05 11:18

  • BugEngineer (作者)

    回复 CODE_XU: 您好。每次都是后边的imageCode.onload不执行,qrcode是后端动态返回的客户二维码,这个我试了下 是可以打开的,而且我也替换过不同的链接。我现在看 还是会不执行 第一个image.onload基本总是执行的

    2022-09-05 13:43

  • CODE_XU

    回复 BugEngineer: 可以提供复现 demo 吗?如果直接拿两张图片测试是不会有问题的

    2022-09-05 14:09

  • BugEngineer (作者)

    回复 CODE_XU: 已更新到回复,麻烦看下 我这mac pro M1 目前每次都不执行了,昨天晚上用家里的win10还可以呢

    2022-09-05 14:27

BugEngineer

BugEngineer (作者)

var XData // x轴坐标  
var YData // Y轴坐标  
var TopData = 70 //二维码距离顶部的距离  
var BottomData = 60 //二维码距离底部的距离  
var LeftData = 60 //二维码距离左侧的距离  
var RightData = 80 //二维码距离底部的距离  
var ImgWidth = 1080 // 固定宽度  
var CodeWidth = 220 //二维码的宽度  
var CodeHeight = 220 //二维码的高度  

/**  
 * @function 返回坐标  
 * @param type 二维码的位置   0:左上  1:右上  2:左下  3:下中  4:右下角  
 * @param height canvas的高度  
 * @return x,y  
 */  

function coordinate(type, height) {  
    switch (Number(type)) {  
        case 0:  
            XData = LeftData;  
            YData = TopData;  
            break;  
        case 1:  
            XData = ImgWidth - RightData - CodeWidth;  
            YData = TopData;  
            break;  
        case 2:  
            XData = LeftData;  
            YData = height - BottomData - CodeHeight;  
            break;  
        case 3:  
            XData = (ImgWidth - CodeWidth) / 2;  
            YData = height - BottomData - CodeHeight;  
            break;  
        case 4:  
            XData = ImgWidth - RightData - CodeWidth;  
            YData = height - BottomData - CodeHeight;  
            break;  
    }  
}  
// 图片转base64  
function getBase64Image(img) {  
  var canvas = document.createElement('canvas')  
  canvas.width = img.width  
  canvas.height = img.height  
  var ctx = canvas.getContext('2d')  
  ctx.drawImage(img, 0, 0, img.width, img.height)  
  const dataURL = canvas.toDataURL('image/jpeg') // 可根据图片后缀,动态变换如 image/png  
  return dataURL  
}  

function imageUrlToBase64({  
    codePosition,  
    url = "",  
    cb = null  
} = {}) {  
    var userData = JSON.parse(uni.getStorageSync("userData"));  
    var mask = userData.shopName || "开发环境" // 水印  
    var qrCode = userData.path // 二维码  
    //一定要设置为let,不然图片不显示  

    let image = document.createElement("img");  
    //解决跨域问题  
    image.setAttribute('crossOrigin', 'anonymous');  
    image.src = url  

    let imageCode = document.createElement("img");  
    imageCode.setAttribute('crossOrigin', 'anonymous');  
    imageCode.src = qrCode  

    var canvas = document.createElement("canvas");  
    var context = canvas.getContext('2d');  
    image.onload = () => {  
        canvas.width = image.width;  
        canvas.height = image.height; //图片大小不同导致不一样 是否可以要求上传的尺寸是相同的  
        coordinate(codePosition, canvas.height)  
        console.log('宽高', canvas.width, canvas.height)  
        context.fillStyle = "#fff"; // 解决透明背景变为黑色问题  
        context.fillRect(0, 0, canvas.width, canvas.height);  
        context.drawImage(image, 0, 0, image.width, image.height);  
        context.font = '50px "微软雅黑"'; //设置字体  
        context.fillStyle = "rgba(51,51,51,0.7)";  
        console.log('imageCode1',imageCode)  
        imageCode.onload = () => {  
            console.log('imageCode2', XData , YData)  
            context.drawImage(imageCode, XData, YData, 220, 220);  
            for (let j = 50; j <= image.height * 2;) {  
                context.fillText(mask, 0, j);  
                j += 260  
            }  
            console.log('imageCode3', XData , YData)  
            //这里的dataurl就是base64类型  
            let originalBase64Url = canvas.toDataURL("image/jpeg",  
                0.8); //使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!        
            cb && cb(originalBase64Url);  
        }  
    }  

}  

export default imageUrlToBase64  

测试url:http://static.hongliaouv.com/2022/09/05/68f0872ff93d4eada1018c51f4ea4010.jpg
测试qrcdoe: http://static.hongliaouv.com/2022/09/05/8e755bcd34a34fe4b107b15c2f8dcf27.png

coordinate是用来动态计算x y坐标的 您那二维码的位置可以先写死

  • CODE_XU

    用这两个地址也未能复现,img.onload 这并非 uni-app 的问题,你可以在不使用 uni-app 的环境下测试一下

    2022-09-05 15:10

  • BugEngineer (作者)

    回复 CODE_XU: 你那每次都能调用成功?和电脑有关系吗 我这今天基本还没成功过。。。

    2022-09-05 15:39

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