canvas圖片問題
做的一個項目需要將兩張圖片合成一張圖片輸出,想到可以用canvas來實現圖片的合成
var self = this;
var codeImg = document.getElementById("qrcode").getElementsByTagName("img")[0];
var bgImg = document.createElement("img");
codeImg.setAttribute("crossOrigin", 'anonymous');
bgImg.setAttribute("crossOrigin", 'anonymous');
var canvas = document.getElementById("myCanvas");
canvas.width = "375";
canvas.height = '667';
var ctx = canvas.getContext("2d");
ctx.rect(0,0,375,667);
ctx.fillStyle = '#fff';
ctx.fill();
通過canvas合成圖片有一個要注意的技術點,就是獲取的img元素,需要設置屬性img.setAttribute("crossOrigin","anonymous")
不設置該屬性的話,就會出現錯誤如下:
Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
實際代碼中我有兩張圖片,一張圖片是本地圖片顯示的,另外一張圖片是通過請求服務器接口url顯示的。
上面的那個錯誤已經解決,卻出現了另外一個錯誤。
這個問題的出現,顯然是跨域限制所導致的。可是我將圖片設置屬性img.setAttribute("crossOrigin","anonymous"),難道是圖片是請求服務器拿到的url,在本地服務器出現的跨域問題?
經過斷點測試,果然是這個坑。然后讓運營的同事配置一下請求接口加上Access-Control-Allow-origin:*,要 OSS 和 CDN 均配置跨域允許。
再重新運行,錯誤沒有了。
移動端iOS系統onload事件失效的問題
在這個圖片合成的過程中,有一個問題就是由於有一個圖片是需要請求服務器顯示的,所以,在用canvas合成的過程中,需要判斷服務器已經下載完成顯示后,才進行ctx.drawImage(),否則就會出錯。這就需要通過onload事件在判斷圖片是否加載完成
bgImg.src = self.imgsrc;
bgImg.addEventListener('load',function() {
self.isShow = true;
ctx.drawImage(bgImg,0,0,375,667);
ctx.drawImage(codeImg,270,568,90,90);
imgURL = canvas.toDataURL("image/png");
var img = new Image();
document.getElementById("imgWrap").appendChild(img);
img.src = imgURL;
self.finalSrc = imgURL;
img.style.width = 100 + '%';
img.style.height = 100 + '%';
canvas.style.display = "none";
})
安裝上面代碼的執行順序,在chorme,firefox瀏覽器上都可以正常合成圖片輸出的,然后在ios手機設配上測試的時候,居然不進入onload這個方法里面.
google了一下,確實是,用到了 window.onload ,在這個事件發生時初始化,然后在 iOS webview 上這個事件不觸發,其他人也遇到了。卻沒有找到解決方法。
但是bgImg.src = self.imgsrc;放在onload事件的后面,這個問題就給繞過去了。
其中的原因我也不是很清楚,大概是iOS需要等待圖片onload事件執行完成,才能操作改圖片的src。以后找到該原因后再補上。