解决在页面中无法获取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>


目录
相关文章
|
1月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
4月前
|
存储 JavaScript 前端开发
JS上传文件(base64字符串和二进制文件流)
这篇文章介绍了两种JavaScript文件上传的方法:使用FileReader对象将文件读取为base64字符串上传,以及使用FormData对象以二进制文件流的形式上传文件,包括如何处理文件选择、读取和上传的详细代码示例。
527 2
JS上传文件(base64字符串和二进制文件流)
|
2天前
|
JavaScript 容器
带方向感知功能的js图片遮罩层插件
带方向感知功能的js图片遮罩层插件
|
4月前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
51 5
|
3月前
|
前端开发 JavaScript API
前端JS读取文件内容并展示到页面上
前端JavaScript使用FileReader API读取文件内容,支持文本类型文件。在文件读取成功后,可以通过onload事件处理函数获取文件内容,然后展示到页面上。
113 2
前端JS读取文件内容并展示到页面上
|
2月前
|
Web App开发 前端开发 JavaScript
JavaScript动态渲染页面爬取——Selenium的使用(一)
JavaScript动态渲染页面爬取——Selenium的使用(一)
65 4
|
2月前
|
Web App开发 数据采集 JavaScript
JavaScript动态渲染页面爬取——Selenium的使用(二)
JavaScript动态渲染页面爬取——Selenium的使用(二)
78 2
|
3月前
|
JavaScript 前端开发
js 回到页面顶部
本文提供了一个JavaScript函数`scrollToTop`,用于平滑滚动页面回到顶部。该函数利用`requestAnimationFrame`和`window.scrollTo`方法逐步减少滚动条距离,直到页面完全回到顶部。
36 1
|
2月前
|
JavaScript 前端开发 API
JavaScript全屏,监听页面是否全屏
JavaScript全屏,监听页面是否全屏
66 0
|
3月前
|
JavaScript 前端开发
js怎么定位不同的页面元素
在JavaScript中,有多种方法定位和选择页面元素。