canvas 圖片合成填坑記

原文鏈接: http://lion1ou.win/2017/12/01/

需求

要用代碼來實現(xiàn)多張外部圖片和文字的合并而且要上傳到七牛云,再將圖片鏈接通過客戶端分享出去土浸。圖片背景需要支持用戶自定義更換橙凳。

實現(xiàn)效果

實現(xiàn)方案

在一個canvas上多次調(diào)用drawImage函數(shù)蕾殴,分別繪制在canvas中,多次之后canvas中是多個圖片合并的效果岛啸,然后再調(diào)用toDataURL函數(shù)將canvas轉(zhuǎn)成dataURL格式的圖片钓觉,再將dataURL格式裝換為blob文件,上傳至七牛云坚踩。

需要注意的坑

canvas圖片模糊的問題

將canvas的長寬設(shè)為樣式長寬的2倍或更大荡灾, 如下:

var canvas = document.getElementById("myCanvas");
canvas.width = "600";
canvas.height = "600"
canvas.style.height = "300px"
canvas.style.height = "300px"

報安全性錯誤

如果你的圖片url和頁面不在同一域下,在調(diào)用toDataURL函數(shù)的時候就會報安全性錯誤瞬铸。chrome中:

Uncaught SecurityError: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

Safari中貌似更嚴格批幌,根域名相同子域不同依然會報錯:

Cross-origin image load denied by Cross-Origin Resource Sharing policy.

原因:

沒有CORS授權(quán)雖然可以在 canvas 中使用圖像, 但這樣做就會污染(taints)畫布。 只要 canvas 被污染, 就不能再從畫布中提取數(shù)據(jù), 也就是說不能再調(diào)用 toBlob(), toDataURL() 和 getImageData() 等方法, 否則會拋出安全錯誤(security error).這實際上是為了保護用戶的個人信息,避免未經(jīng)許可就從遠程web站點加載用戶的圖像信息,造成隱私泄漏嗓节。

解決方法:

為每個圖片創(chuàng)建一個新的img對象荧缘,再賦給其src等參數(shù),用這種方式要等到img加載完畢再進行canvas其他操作拦宣,在img的load事件處理函數(shù)中進行操作截粗,否則可能會繪制出空內(nèi)容信姓。

let img = new Image()
img.setAttribute('crossorigin', 'anonymous')
img.src = imgUrl
img.onload = function () {
    // do Something
}
img.error = function () {}

在mac和pc的瀏覽器上運行正常,但是在ios11以下的手機內(nèi)無法toDataURL

解決辦法:

  • 改變圖片的載入方式绸罗,先在DOM上新建img標簽财破,如下:
<img crossOrigin="Anonymous" id="bgImg" src="https://www.test.com/test.png" alt="">

注意:crossOrigin="Anonymous"一定要在src屬性前面

被這個坑了很久

  • 利用js獲取img元素
var img = document.getElementById('bgImg')
ctx.drawImage(img, 0, 0, 700, 700)

canvas.toBlob() safari上無效

解決辦法:

將canvas使用toDataURL方法轉(zhuǎn)為base64,再將base64通過file API 轉(zhuǎn)為 blob

function dataURLtoBlob (dataurl) { // 將dataUrl 轉(zhuǎn)為 Blob
  let arr = dataurl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
      u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], {type: mime})
}
var resultBase64 = canvas.toDataURL('image/jpeg') // 轉(zhuǎn)為jpeg壓縮圖片大小
var canvasBlob = dataURLtoBlob(resultBase64)

轉(zhuǎn)載請標注原文地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市从诲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌靡羡,老刑警劉巖系洛,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異略步,居然都是意外死亡描扯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門趟薄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绽诚,“玉大人,你說我怎么就攤上這事杭煎《鞴唬” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵羡铲,是天一觀的道長蜂桶。 經(jīng)常有香客問我,道長也切,這世上最難降的妖魔是什么扑媚? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮雷恃,結(jié)果婚禮上疆股,老公的妹妹穿的比我還像新娘。我一直安慰自己倒槐,他們只是感情好旬痹,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著讨越,像睡著了一般唱凯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谎痢,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天磕昼,我揣著相機與錄音,去河邊找鬼节猿。 笑死票从,一個胖子當著我的面吹牛漫雕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播峰鄙,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼浸间,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吟榴?” 一聲冷哼從身側(cè)響起魁蒜,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吩翻,沒想到半個月后兜看,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡狭瞎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年细移,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熊锭。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡弧轧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碗殷,到底是詐尸還是另有隱情精绎,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布锌妻,位于F島的核電站捺典,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏从祝。R本人自食惡果不足惜襟己,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牍陌。 院中可真熱鬧擎浴,春花似錦、人聲如沸毒涧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽契讲。三九已至仿吞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捡偏,已是汗流浹背唤冈。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留银伟,地道東北人你虹。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓绘搞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親傅物。 傳聞我的和親對象是個殘疾皇子夯辖,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容