最近由于公司業(yè)務(wù)要求顽腾,需要完成一個(gè)一鍵生成照片海報(bào)的功能珊佣,功能的核心是把HTML代碼展現(xiàn)的內(nèi)容轉(zhuǎn)化為png或者jpg圖片堂油。接到這個(gè)任務(wù)的時(shí)候棒卷,我心里是一臉懵逼的古沥,于是就上谷歌搜索插件,還真有一款名叫html2canvas的插件娇跟,我心想看來(lái)這任務(wù)還是挺簡(jiǎn)單的,那開(kāi)始吧太颤!
html2canvas
運(yùn)行腳本苞俘,可以直接在用戶(hù)瀏覽器上拍攝網(wǎng)頁(yè)或其部分的“截圖”。截圖是基于DOM龄章,因此并不是100%準(zhǔn)確的真實(shí)表示吃谣,因?yàn)樗菍?shí)際的截圖,而是根據(jù)頁(yè)面上可用的信息構(gòu)建截圖做裙。(引用自html2canvas官網(wǎng))
入門(mén)
html2canvas的簡(jiǎn)單調(diào)用:
// element是需要截圖的元素
html2canvas(element岗憋,options);
可用選項(xiàng)(options)
參數(shù)名稱(chēng) | 類(lèi)型 | 默認(rèn)值 | 描述 |
---|---|---|---|
allowTaint | boolean | false | 允許跨域 |
useCORS | boolean | false | 貌似與跨域有關(guān),但和allowTaint不能共存 |
proxy | string | undefined | 代理地址 |
taintTest | boolean | true | 是否在渲染前測(cè)試圖片 |
timeout | number | 0 | 圖片加載延遲锚贱,默認(rèn)延遲為0仔戈,單位毫秒 |
logging | boolean | false | 在Console中輸出信息 |
width | number | null | canvas的寬度設(shè)定 |
height | number | null | canvas的高度設(shè)定 |
background | string | #fff | canvas的背景顏色(未指定則為透明) |
letterRendering | boolean | false | 在設(shè)置了字間距的時(shí)候有用 |
特別的是,html2canvas提供了回調(diào)事件--onrendered來(lái)渲染canvas:
html2canvas(element拧廊,{
onrendered:function(canvas){
// canvas是最終渲染的<canvas>元素
}
});
我想有這些已經(jīng)足夠了吧监徘,于是寫(xiě)下了這樣的代碼:
// vue.js
// html
<div class="box">

</div>
<button @cllick="doShot">截圖</button>
// js
doShot () {
const w = $('.box').outerWidth(),
h = $('.box').outerHeight();
html2canvas($(".box"), {
allowTaint: true,
taintTest: false,
width: w,
height: h,
onrendered: function(canvas) {
var dataUrl = canvas.toDataURL("image/png", 1.0),
newImg = document.createElement("img");
newImg.src = dataUrl;
$('.box').empty().append(newImg);
newImg.style.width = '100%';
}
});
}
在chrome開(kāi)發(fā)者工具中截圖效果還不錯(cuò),孰知在移動(dòng)設(shè)備--iphone6中測(cè)試的時(shí)候竟然是這般模樣:
從圖中的英文字母可以看出吧碾,圖中的像素發(fā)生了偏移凰盔,給人的視覺(jué)感受是圖片變模糊了,這可咋辦呀倦春!于是我又一次借助萬(wàn)能的google去尋求答案户敬,但是答案大同小異落剪,如下圖:
但是,并沒(méi)有什么作用尿庐,就在我萬(wàn)念俱灰的時(shí)候忠怖,在原作者的git上看到了#1087 自定義分辨率
的解決方法,作者在html2canvas的源碼中添加了兩個(gè)參數(shù)屁倔,分別為scale和dpi脑又,scale是比例,辣么dpi是個(gè)什么玩意兒锐借,以下是百度百科對(duì)dpi的定義:
DPI是指每英寸的像素问麸,也就是掃描精度。DPI越低钞翔,掃描的清晰度越低严卖,由于受網(wǎng)絡(luò)傳輸速度的影響,web上使用的圖片都是72dpi布轿,但是沖洗照片不能使用這個(gè)參數(shù)哮笆,必須是300dpi或者更高350dpi。例如要沖洗46英寸的照片汰扭,掃描精度必須是300dpi稠肘,那么文件尺寸應(yīng)該是(4300)(6300)=1200像素*1800像素。
好啦萝毛,到這里我們應(yīng)該知道项阴,只要增大dpi或者scale肯定能使同樣寬高的圖像變得清晰,那么模糊的問(wèn)題也就不存在了笆包。
參數(shù)用法介紹:
參數(shù)名稱(chēng) | 類(lèi)型 | 默認(rèn)值 | 描述 |
---|---|---|---|
scale | number | 1 | 按比例增加分辨率 (2=雙倍). |
dpi | number | 96 | 將分辨率提高到特定的DPI(每英寸點(diǎn)數(shù)) |
以下是增加了dpi和scale兩個(gè)選項(xiàng)之后的html2canvas源碼(拿走不謝):
https://github.com/eKoopmans/html2canvas/tree/develop/dist
最后將上面的html2canvas.js下載到本地环揽,并引入到項(xiàng)目中:
// vue.js
// html
<div class="box">

</div>
<button @cllick="doShot">截圖</button>
// js
doShot () {
const w = $('.box').outerWidth(),
h = $('.box').outerHeight();
html2canvas($(".box"), {
allowTaint: true,
taintTest: false,
width: w,
height: h,
// window.devicePixelRatio是設(shè)備像素比
scale: window.devicePixelRatio,
onrendered: function(canvas) {
const dataUrl = canvas.toDataURL("image/png", 1.0),
newImg = document.createElement("img");
newImg.src = dataUrl;
$('.box').empty().append(newImg);
newImg.style.width = '100%';
}
});
}
最終的截圖效果如下:
如果大家還有什么更好的解決辦法,請(qǐng)分享一下庵佣!