App下載

怎么使用html5中的canvas對(duì)多圖片進(jìn)行拼合? 案例代碼分享!

猿友 2021-07-16 09:39:12 瀏覽數(shù) (2188)
反饋

在沒(méi)有微信之前我們很多小伙伴們應(yīng)該都是使用QQ吧!那么隨著技術(shù)的發(fā)展越來(lái)越多的人使用微信人們可以把自己的見(jiàn)聞和心情發(fā)到上面,那么這次我們就來(lái)說(shuō)說(shuō)有關(guān)于:“怎么使用html5中的canvas對(duì)多圖片拼合并導(dǎo)出圖片?”這個(gè)問(wèn)題吧!

先說(shuō)下canvas繪圖的基本方法,如下:

const myCanvas = document.createElement('canvas');
    myCanvas.width = 400;
    myCanvas.height = 400;
const ctx = myCanvas.getContext('2d');
const img = new Image();
img.src = "1.jpg";
//當(dāng)圖片加載完畢的時(shí)候在drawImage,否則可能圖片還沒(méi)有加載完畢
img.onload=()=>{
    ctx.drawImage(img, 0, 0, 100, 50);
}

語(yǔ)法:

?drawImage(image, x, y)?

以 canvas 上指定的坐標(biāo)點(diǎn)開(kāi)始,按照?qǐng)D像的原始尺寸大小繪制整個(gè)圖像。

?drawImage(image, x, y, width, height)?

以canvas上指定的坐標(biāo)點(diǎn)開(kāi)始,以指定的大小(?width?和?height?)繪制整個(gè)圖像,圖像會(huì)自動(dòng)縮放。

?drawImage(image, imageX, imageY, imageWidth, imageHeight, x, y, width, height)?

將指定圖像的局部圖像(以(?imageX?, ?imageY?)為左上角、寬度為?imageWidth?、高度為?imageHeight?的矩形部分)繪制到 canvas 中以?( x, y)?為左上角坐標(biāo)、寬度為?width?、高度為?height?的矩形區(qū)域中

這次多圖拼合的業(yè)務(wù)場(chǎng)景是做不同內(nèi)容的定制分享圖片,用到的圖片元素有,背景圖片、外鏈圖片、網(wǎng)站logo、定制生產(chǎn)的二維碼圖,需要解決的問(wèn)題,都是在畫布轉(zhuǎn)圖片輸出時(shí)產(chǎn)出的。主要有3點(diǎn):

1、圖片的跨域問(wèn)題;
2、繪制多圖,造成的畫布污染;
3、圖片的大??;

首先圖片的跨域問(wèn)題,這個(gè)問(wèn)題在網(wǎng)上已經(jīng)有很多相關(guān)信息,解決辦法如下:

img.setAttribute('crossOrigin', 'anonymous');

當(dāng)解決完跨域問(wèn)題后,在多圖拼合導(dǎo)出后,出現(xiàn)了新的報(bào)錯(cuò)信息:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted Canvases may not be exported.

我發(fā)現(xiàn)這個(gè)問(wèn)題時(shí),查看網(wǎng)上的資料,大多也是用上面的跨域方法解決的,可是我明顯在我的業(yè)務(wù)場(chǎng)景里是不管用的。

通過(guò)對(duì)代碼的排查,我發(fā)現(xiàn),背景圖+二維碼圖時(shí),并不會(huì)報(bào)這個(gè)錯(cuò)誤,如外鏈圖片做了跨域處理,單獨(dú)使用時(shí),也不會(huì)報(bào)錯(cuò)。而logo圖片都是本地的文件,顯然不應(yīng)該是跨域問(wèn)題。

那么二維碼圖和背景圖能夠不出錯(cuò)的原因,應(yīng)該在于二維碼圖片源是base64格式的。

于是,我試著將 logo 圖使用畫布導(dǎo)出 base64 格式,然后和背景圖+二維碼圖進(jìn)行拼合,導(dǎo)出時(shí)果然沒(méi)再報(bào)錯(cuò)。

所有解決多圖拼合導(dǎo)出時(shí),Tainted Canvases 的問(wèn)題,應(yīng)該是將圖片元素做成 base64 的格式,就能夠避免了。

因?yàn)槲业臉I(yè)務(wù)場(chǎng)景中有外鏈圖片,而且不是所有的外鏈都對(duì)我網(wǎng)站域名做了跨域允許的處理,所以,在生成外鏈圖片的 base64 數(shù)據(jù)時(shí),可是使用 img.onerror 事件的處理,用缺省圖替換。

因?yàn)橛性诋嬁倛D之前,有對(duì)多圖的分別處理,因此,使用 Promise 處理可能會(huì)更好一些。

在圖片導(dǎo)出的大小問(wèn)題上,導(dǎo)出時(shí)盡量使用

myCanvas.toDataURL('image/jpeg', encoderOptions)

encoderOptions:可以從0到1的區(qū)間內(nèi)選擇圖片的質(zhì)量。如果超出取值范圍,將會(huì)使用默認(rèn)值 0.92。其他參數(shù)會(huì)被忽略。

通過(guò)這篇文章相信大家對(duì)于:“怎么使用html5中的canvas對(duì)多圖片拼合并導(dǎo)出圖片?”這個(gè)問(wèn)題也有所了解了,當(dāng)然如果在html5中可以實(shí)現(xiàn)的內(nèi)容當(dāng)然不知如此了,更多的相關(guān)內(nèi)容和知識(shí)我們都可以W3Cschool中進(jìn)行學(xué)習(xí)和了解。 那么今天的分享就到這邊,希望對(duì)大家的學(xué)習(xí)和了解有所幫助!


0 人點(diǎn)贊