前端動態生成二維碼后合成海報,下載分享


轉載:https://blog.csdn.net/zgh0711/article/details/88192993

如何生成二維碼

現在前端環境下,要生成二維碼,可用的工具庫有很多,我這里用的是 qrcode,首先安裝

  npm install --save qrcode

安裝完之后 import 導入就能使用了

  import QRCode from 'qrcode'

一,將生成的二維碼通過 canvas 標簽展示

<canvas class="qr" id="qrCode-canvas"></canvas>
let canvas = document.getElementById('qrCode-canvas')
        QRCode.toCanvas(canvas, this.qrCodeUrl, (error) => {
          if (error) {
            console.log(error)
          } else {
            canvas.style.width = '1.68rem'
            canvas.style.height = '1.68rem'
            });
          }
 })

  二維碼生成好后,有需要的話可以調整下 canvas 的大小等屬性,因為 qrcode 生成的二維碼會帶有一些默認樣式,需要調整下。

二,先通過 canvas 生成二維碼,然后將 canvas 的內容轉為 base64 格式以 img 標簽展示

<img class="qr" id="qr-img" :src="dataUrl" alt="邀請二維碼"/>

let img = document.getElementById('qr-img')
        let canvas = document.createElement('canvas')
        canvas.width = img.width
        canvas.height = img.height
        //用 canvas 對象和邀請鏈接生成二維碼,並將生成的二維碼轉為 base64
        QRCode.toCanvas(canvas, this.qrCodeUrl, (error) => {
          if (error) {
            console.log(error)
          } else {
            this.dataUrl = canvas.toDataURL("image/jpeg")
            });
          }
})

上面兩種方式都可以生成二維碼並顯示在界面上,區別在於第一種是以 canvas 標簽顯示,在微信中長按是無法識別的。第二種是以 img 標簽顯示,在微信中長按會自動識別並可以直接以圖片形式分享出去。

做到這一步,需求已經完成了一半,下一步就是按設計圖要求把二維碼定位到海報背景上,將二維碼和海報合成為一張圖片。之所以要合成為一張圖片還是為了讓用戶在微信中操作方便。合成為一張圖片后,用戶在微信中直接長按合成后的海報就可以分享或者識別二維碼。

合成海報時碰到的坑

合成海報時需要用到另一個工具庫 html2canvas ,基本使用方法也很簡單,先獲取要合成圖片的 dom 對象,然后調用 html2canvas ,它會返回一個 promise,里面的 canvas 就是合成后的圖片信息,同樣的,這里的 canvas 可以直接顯示出來,也可以轉成 base64 之后放到 img 標簽里顯示,但是為了分享或者下載方便,基本都是轉成了 base64

let poster = document.getElementById('poster')
            html2canvas(poster).then(canvas => {
              this.posterDataUrl = canvas.toDataURL()
});

到這里,基本需求就完成了。然而世界上的事情往往都不會是一帆風順的,在測試的時候發現出了問題。

我前面二維碼是用上面說的第二種方法顯示的,將二維碼的 canvas 轉成了 base64 顯示在 img 標簽上,再將這個二維碼 img 和海報背景 img 合成。這樣的實現方式在 iOS 和瀏覽器中都沒有問題,然而在安卓版微信里面卻是只有海報背景而沒有二維碼。

在查了N多資料和嘗試了好多遍之后終於發現,是因為我的二維碼是 base64 的,如果二維碼是以 canvas 形式顯示,再去合成海報,將合成后的海報轉為 base64 就沒有問題了。 所以我在前面寫生成二維碼的時候寫了二種方法。至此,整個需求也就真正的完成了。

下面是完整代碼

<template>
  <div class="ypl-flex">
    <mt-header title="邀請用戶" go-back></mt-header>
    
    <div class="invitePosterPage flex">
      <p class="title">分享專屬海報,邀請用戶注冊,即可成功邀請</p>
      <p class="remark">(注:只能通過此二維碼注冊用戶才可成功邀請)</p>
      
      <img v-if="posterDataUrl" :src="posterDataUrl" class="poster-bg" alt="邀請海報"/>
      <div v-else id="poster" class="flex-row" style="position: relative">
        <img class="poster-bg" src="../../../assets/img/img_poster_bg.png" alt="邀請海報背景"/>
        <canvas class="qr" id="qrCode-canvas"></canvas>
      </div>
    </div>
  </div>
</template>

<script>
  /**
   * 這是邀請海報組件
   */
  import QRCode from 'qrcode'
  import html2canvas from 'html2canvas';
  
  export default {
    name: 'Poster',
    data () {
      return {
        posterDataUrl:'',
        qrCodeUrl: 'https://www.baidu.com'
      }
    },
  
    async mounted () {
    	this.createQRCode()
    },
    
    methods: {
      createQRCode () {
        //先用 QRCode 生成二維碼 canvas,然后用 html2canvas 合成整張海報並轉成 base64 顯示出來
        let canvas = document.getElementById('qrCode-canvas')
        QRCode.toCanvas(canvas, this.qrCodeUrl, (error) => {
          if (error) {
            console.log(error)
          } else {
            //qrcode 生成的二維碼會帶有一些默認樣式,需要調整下
            canvas.style.width = '1.68rem'
            canvas.style.height = '1.68rem'
            
            let poster = document.getElementById('poster')
            html2canvas(poster).then(canvas => {
              this.posterDataUrl = canvas.toDataURL()
            });
          }
        })
      }
    },
  }
</script>

  

這次做這個需求的過程中,查到了一些 html2canvas 的資料,有很多文章都提到 html2canvas 有一些坑,我是沒碰到,現在將這些文章列出來,給需要的人。
html2canvas 用法詳解
Html2canvas - 項目中遇到的那些坑點匯總(更新中…)
一次 H5 「保存頁面為圖片」 的踩坑之旅
微信H5實現網頁長按保存圖片及識別二維碼
基於html2canvas實現網頁保存為圖片及圖片清晰度優化
Vue.js結合Canvas制作二維碼和圖片的合成(qrcanvas + html2canvas)

然后就是 canvas 轉 base64 的 .toDataURL()] 這個方法,這個方法里面其實是可以配置參數的,有需要的可以去看下這個文檔
HTMLCanvasElement.toDataURL()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM