基於canvas生成圖片

隨着APP的獲客成本愈來愈高,不少產品開始從wap頁引流,而最多見的方式即是分享,尤爲是在微信中。所以誕生了一些新玩法,好比生成一張海報圖片,用戶能夠保存或分享到其餘平臺。html

本文將介紹如何生成一張海報圖片,以及可能會碰到的問題和解決方案。git

canvas轉圖片

目前移動端瀏覽器對於canvas的支持很是好,而canvas能夠經過toDataURL來轉換成base64圖片。github

市場上的一些js庫,如:html2canvasdom-to-image,其本質也是經過toDataURL來轉換成圖片。但我我的不太建議使用這類js庫,由於你可能須要填不少坑,結果也並不必定能達到你的指望,因此仍是老老實實用canvas畫出來吧。canvas

外鏈圖片

最重要也是最複雜的即是對外鏈圖片的處理,canvas繪圖時不會有任何問題,可是調用toDataURL這個方法時,瀏覽器會報錯。跨域

跨域瀏覽器

你請求的外域圖片,可能會暴露你的隱私,因此瀏覽器爲了保護你的隱私限制了這樣的請求。緩存

咱們能夠設置crossOriginanonymous來容許跨域,瀏覽器會爲這張圖片的請求頭附帶Origin信息,告訴靜態資源服務器,請在響應頭中附帶Access-Control-Allow-MethodsAccess-Control-Allow-Origin,以便瀏覽器放行。服務器

可是有些時候,設置了crossOrigin依然會報錯,其實不是設置了沒有做用,而是cdn緩存了服務器響應結果,這個結果每每是沒有上述兩個字段的。這個時候能夠考慮給圖片連接後追加時間戳,對於cdn來講,這是一個沒有請求過的資源,所以它會從源服務器去拿數據。微信

代碼示例以下:app

var img = new Image()
img.crossOrigin = 'anonymous'
img.onload = function () {
  // 在圖片加載完成後繪圖,避免空白和斷斷續續加載
  ctx.drawImage(img, 0, 0)
}
img.src = 'https://xxxx' + '?' + (+new Date())

保存圖片

a標籤有一個download屬性,能夠將指定的資源下載下來,但該方法只適用於pc端,移動端基本不支持(Safari會打開一個base64的網頁,而在微信中甚至不會有任何響應,更不用提衆多的安卓機)。

既然不能在瀏覽器主動保存圖片,咱們只好另闢蹊徑,經調研發現:如今絕大多數的移動端瀏覽器都支持長按圖片喚起下拉菜單來保存,所以咱們能夠經過文案提示用戶進行操做,但它的弊端是沒有API來調用,也就是說只能提示用戶自發地進行長按保存操做,而咱們對於用戶是否保存了圖片是無感知的。

文末總結

對於目前的產品需求,長按圖片保存基本可以知足要求。因此,目前的作法是:經過canvas繪製一張海報圖片,將其轉換爲base64圖片,建立img標籤並渲染到視圖上,文字提示用戶長按能夠保存(只有在圖片上長按纔有效)。

示例代碼:

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')

canvas.width = 300
canvas.height = 300

// 畫圓
ctx.fillStyle = 'yellow'
ctx.fillRect(0, 0, 50, 100)

ctx.strokeStyle = 'blue'
ctx.strokeRect(0, 120, 50, 100)

var img = new Image()
img.onload = () => {
  // 畫圖片
  ctx.drawImage(img, 60, 0)
  // toImage
  var dataImg = new Image()
  dataImg.src = canvas.toDataURL('image/png')
  document.body.appendChild(dataImg) // 長按圖片保存
}
img.crossOrigin = 'anonymous'
img.src = 'https://nos.netease.com/easyread/fle/a0df1d4009c7a2ec5fee/1524215500140/avatar.png?' + (+new Date())
相關文章
相關標籤/搜索