解决在页面中无法获取qrcode.js生成的base64的图片

简介: 该文档介绍了如何解决在部分安卓手机上无法正确加载二维码图片的问题。之前的方法是使用qrcode.js生成二维码,然后与背景图结合用canvas绘制海报,但在某些安卓设备上遇到onload事件不触发的问题。

应用场景


生成带二维码的推广海报图片


旧方法


将用户自己的推广连接先通过qrcode.js生成二维码,然后再用后台返回的一张背景图片和二维码通过canvas绘制成一张海报。


问题


在部分安卓手机上获取二维码图片后,onload事件不起作用,代码演示如下。

<!---放二维码--->
<div id="imgs" style="width:100px; height:100px; margin-top:15px;"hidden></div>
<!-- 生成canvas海报 -->
<canvas id="myCanvas" width="" height=""></canvas>
<!-- 生成canvas海报 -->
<!--海报弹窗-->
<div class="shadow" onclick="shareHide()"></div>
<img  class="shareImg" id="imgShow" src="">
<script type="text/javascript">
    document.onreadystatechange = loadingChange;  // 当页面加载状态改变的时候执行这个方法.  
    function loadingChange()   
    {     
          if(document.readyState == "Loading") {    // 当页面加载状态为完全结束时进入 
            // $(".shodowS").show() 
          }
          if(document.readyState == "complete") {   // 当页面加载状态为完全结束时进入 
        var qrcodes = new QRCode(document.getElementById("imgs"), {
          width : 160,
          height : 160
        });
        qrcodes.makeCode('{$url}');        // 生成二维码
        shareImgs();
          }
      }
  
    var canvas = document.getElementById('myCanvas');
  canvas.width=$("#container").width()*2;
  canvas.height=$("#container").width()*1440/1080*2;
  $("#myCanvas").css("width",$("#container").width());
  $("#myCanvas").css("height",$("#container").width()*1440/1080);
  // 分享图片生成的
  function shareImgs() {
    var qrcode=document.getElementById("imgss");
    if (canvas.getContext) {
      var ctx = canvas.getContext('2d');
      //创建新的图片对象
      var img = document.getElementById("imgs1");
      var img = new Image;
      
      //指定图片的URL
      // img.crossOrigin="anonymous";         // 这个可以对苹果手机做兼容(跨域)
      // img.src=img.src;
      img.src='{$bg[0]}';
      img.onload = function() {
        var imgOw=img.width,imgOh=img.height;
        var imgW=canvas.width,imgH=(imgOh*canvas.width)/imgOw;
        var imgX=0,imgY=0;
        //以Canvas画布上的坐标(10,10)为起始点,绘制图像
        ctx.drawImage(img, imgX, imgY,imgW,imgH);     
        var qrcodeX, qrcodeY,qrcodeW,qrcodeH;
        qrcode.crossOrigin="anonymous";
        qrcode.src=qrcode.src;
        qrcode.onload = function() {
          //以Canvas画布上的坐标(10,10)为起始点,绘制图像
          ctx.drawImage(qrcode,846/1080*canvas.width, 1220/1440*(imgOh*canvas.width)/imgOw+(canvas.height-imgH)/2, 160/1440*img.width, 160/1440*img.width); 
          var _imgSrc = canvas.toDataURL("image/png",1);
             var imgShow = document.getElementById('imgShow');
                 imgShow.setAttribute('src', _imgSrc);
        }   
      }
    }
  }
       
</script>


解决方法


虽然知道是页面渲染的先后问题,但是时间很紧,只能跳过使用另一种方式解决这种在有的手机上不能生成海报的问题。所以决定通过后台生成二维码放在页面,然后JS只需要获取后台返回的base64二维码和海报绘制再生成图片,最后安卓苹果手机都能显示了。


1. 使用的是phpqrcode类,不过需要简单的修改一下,让其能生成base64的二维码,这个我是在网上参考别人的源码,具体是谁忘记了,记起后代码原著我会补上,这里就代码先上了。


2.  PHP后台生成并返回

/*生成二维码**/
      //打开缓冲区
      ob_start();
      //生成二维码图片
      $returnData = QRcode::pngString($url,false, "H", 3, 1);
      //这里就是把生成的图片流从缓冲区保存到内存对象上,使用base64_encode变成编码字符串,通过json返回给页面。
      $imageString = base64_encode(ob_get_contents());
      //关闭缓冲区
      ob_end_clean();
      $shareQrcode = "data:image/png;base64,".$imageString;
    /**生成二维码*/


3. 前端显示二维码,并js获取重新绘制

<!-- 二维码图片 -->
<img src="{$bg[0]}" hidden="hidden" id="imgs1">
<!--PHP生成的二维码-->
<img src="{$shareQrcode}" hidden="hidden" id="phpQrcodeImg">
<script type="text/javascript">
  var canvas = document.getElementById('myCanvas');
  canvas.width=$("#container").width()*2;
  canvas.height=$("#container").width()*1440/1080*2;
  $("#myCanvas").css("width",$("#container").width());
  $("#myCanvas").css("height",$("#container").width()*1440/1080);
  // 分享图片生成的
  function shareImgs() {
    var qrcode=document.getElementById("imgss");
    var testQrcode = document.getElementById("phpQrcodeImg");
    
    if (canvas.getContext) {
      var ctx = canvas.getContext('2d');
      //创建新的图片对象
      var img = document.getElementById("imgs1");
      var img = new Image;
      
      img.src='{$bg[0]}';
      img.onload = function() {
        var imgOw=img.width,imgOh=img.height;
        var imgW=canvas.width,imgH=(imgOh*canvas.width)/imgOw;
        var imgX=0,imgY=0;
        //以Canvas画布上的坐标(10,10)为起始点,绘制图像
        ctx.drawImage(img, imgX, imgY,imgW,imgH);     
        
        // js生成二维码在部分安卓机上无法获取到二维码图片资源最后onload不到
        var qrcodeX, qrcodeY,qrcodeW,qrcodeH;
        qrcode.crossOrigin="anonymous";
        qrcode.src=qrcode.src;
        
        // 修改为PHP生成的二维码
        testQrcode.crossOrigin="anonymous";
        testQrcode.src = testQrcode.src;
        
        testQrcode.onload = function() {
          //以Canvas画布上的坐标(10,10)为起始点,绘制图像
          ctx.drawImage(testQrcode,846/1080*canvas.width, 1220/1440*(imgOh*canvas.width)/imgOw+(canvas.height-imgH)/2, 160/1440*img.width, 160/1440*img.width); 
          var _imgSrc = canvas.toDataURL("image/png",1);
              // canvas.style.display="none";
             var imgShow = document.getElementById('imgShow');
                 imgShow.setAttribute('src', _imgSrc);
        }   
      }
    }
  }
</script>


目录
相关文章
|
12天前
|
JavaScript
JS代码动态打印404页面源码
源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
12 0
JS代码动态打印404页面源码
|
18天前
|
JavaScript
js中readAsDataURL的意思,可以用于浏览器预览图像文件或者转成base64字符串
js中readAsDataURL的意思,可以用于浏览器预览图像文件或者转成base64字符串
js中readAsDataURL的意思,可以用于浏览器预览图像文件或者转成base64字符串
|
7天前
|
存储 资源调度 前端开发
JavaScript 使用axios库发送 post请求给后端, 给定base64格式的字符串数据和一些其他参数, 使用表单方式提交, 并使用onUploadProgress显示进度
使用 Axios 发送包含 Base64 数据和其他参数的 POST 请求时,可以通过 `onUploadProgress` 监听上传进度。由于整个请求体被视为一个单元,所以进度可能不够精确,但可以模拟进度反馈。前端示例代码展示如何创建一个包含 Base64 图片数据和额外参数的 `FormData` 对象,并在上传时更新进度条。后端使用如 Express 和 Multer 可处理 Base64 数据。注意,实际进度可能不如文件上传精确,显示简单加载状态可能更合适。
|
12天前
|
测试技术 UED
断网之后的页面,Autox.js是点击还是上下滑动比较好?
断网之后的页面,Autox.js是点击还是上下滑动比较好?
|
12天前
|
测试技术 API Android开发
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
|
17天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的图片推荐系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的图片推荐系统附带文章源码部署视频讲解等
13 0
|
18天前
|
JavaScript
js 滚动鼠标滑轮放大缩小图片
js 滚动鼠标滑轮放大缩小图片
10 0
|
18天前
|
前端开发 JavaScript
js 打开资源管理器(经典范例:纯前端选择并预览图片)
js 打开资源管理器(经典范例:纯前端选择并预览图片)
30 0
|
19天前
|
JavaScript API
前后端数据交互.js文件的axios的写法,想要往后端发送数据,页面注入API,await的意思是同步等待服务器数据,并返回,axios注入在其他页面,其他页面调用的时候,同步作用
前后端数据交互.js文件的axios的写法,想要往后端发送数据,页面注入API,await的意思是同步等待服务器数据,并返回,axios注入在其他页面,其他页面调用的时候,同步作用
|
20天前
|
JavaScript 前端开发
前端 JS 经典:统一 Vite 中图片转换逻辑
前端 JS 经典:统一 Vite 中图片转换逻辑
13 0