使用 HTML5 畫布和 SVG 從 DOM 節點產生圖片。
從 dom 到 image 的 fork 具有更易於維護的程式碼和一些新功能。
npm install --save html-to-image
/* ES6 */import * as htmlToImage from 'html-to-image';import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image';/* ES5 */var htmlToImage = require(' html 到圖片');
所有頂層函數都接受 DOM 節點和渲染選項,並傳回一個用對應的 dataURL 履行的承諾:
到Svg
轉Png
轉Jpeg
到Blob
到像素數據
請看以下範例。
取得 PNG 圖像 base64 編碼的資料 URL 並立即顯示它:
var node = document.getElementById('my-node');htmlToImage.toPng(node) .then(function (dataUrl) {var img = new Image();img.src = dataUrl;document.body.appendChild(img); }) .catch(function (error) {console.error('哎呀,出了問題!', error); });
取得 PNG 圖片 base64 編碼的資料 URL 並下載它(使用 download):
htmlToImage.toPng(document.getElementById('my-node')) .then(function (dataUrl) {download(dataUrl, 'my-node.png'); });
取得 PNG 映像 blob 並下載它(使用 FileSaver):
htmlToImage.toBlob(document.getElementById('my-node')) .then(function (blob) {window.saveAs(blob, 'my-node.png'); });
儲存並下載壓縮的 JPEG 影像:
htmlToImage.toJpeg(document.getElementById('my-node'), { 質量: 0.95 }) .then(function (dataUrl) {var link = document.createElement('a');link.download = 'my-image-name.jpeg';link.href = dataUrl;link.click(); });
取得 SVG 資料 URL,但過濾掉所有<i>
元素:
函數濾波器(節點){ return (node.tagName !== 'i');}htmlToImage.toSvg(document.getElementById('my-node'), { filter: 過濾器 }) .then(function (dataUrl) {/* 做某事 */ });
取得 Uint8Array 形式的原始像素數據,其中每 4 個陣列元素代表像素的 RGBA 資料:
var node = document.getElementById('my-node');htmlToImage.toPixelData(node) .then(函數(像素) {for (var y = 0; y < node.scrollHeight; ++y) { for (var x = 0; x < node.scrollWidth; ++x) {pixelAtXYOffset = (4 * y ) * node.scrollHeight) + (4 * x);/* PixelAtXY 是一個Uint8Array[4],包含(x, y) 處像素的RGBA 值,範圍為0..255 */pixelAtXY = Pixels.slice(pixelAtXYOffset, PixelAtXYOffset + 4); });
取得一個 HTMLCanvasElement,並立即顯示它:
htmlToImage.toCanvas(document.getElementById('my-node')) .then(function (canvas) {document.body.appendChild(canvas); });
以 DOM 節點作為參數的函數。如果傳遞的節點應包含在輸出中,則應傳回 true。排除節點意味著也排除它的子節點。
不在根節點上呼叫。
背景顏色的字串值,任何有效的 CSS 顏色值。
在渲染之前應用於節點的寬度和高度(以像素為單位)。
在渲染之前將其屬性複製到節點樣式的物件。您可能需要檢查此參考以取得 CSS 屬性的 JavaScript 名稱。
0
到1
之間的數字,表示 JPEG 影像的影像品質(例如0.92
=> 92%
)。
預設為1.0
( 100%
)
設定為 true 可將目前時間作為查詢字串附加到 URL 請求以啟用快取清除。
預設為false
取得影像失敗時將使用的佔位符影像的資料 URL。
預設為空字串,將為失敗的影像渲染空白區域。
它在最新的 Chrome 和 Firefox(撰寫本文時分別為 49 和 45)上進行了測試,Chrome 在大型 DOM 樹上的性能明顯更好,這可能是因為它具有更高性能的 SVG 支持,並且它支持CSSStyleDeclaration.cssText
屬性。
Internet Explorer 不受(也不會受)支持,因為它不支援 SVG <foreignObject>
標記。
Safari 不受支持,因為它在<foreignObject>
標記上使用更嚴格的安全模型。建議的解決方法是使用toSvg
並在伺服器上渲染。
目前僅使用標準庫,但請確保您的瀏覽器支援:
承諾
SVG <foreignObject>
標籤
可能有一天存在(或者可能已經存在?)一種將 HTML 部分導出到圖像的簡單而標準的方法(然後這個腳本只能作為我必須跳過的所有障礙的證據才能獲得這樣的結果)顯然已經完成了)但到目前為止我還沒找到。
該庫使用 SVG 的一項功能,允許在<foreignObject>
標記內包含任意 HTML 內容。因此,為了為您渲染 DOM 節點,需要執行以下步驟:
遞歸克隆原始 DOM 節點
計算節點和每個子節點的樣式並將其複製到相應的克隆
並且不要忘記重新創建偽元素,因為它們當然不會以任何方式克隆
嵌入網頁字體
尋找所有可能代表網頁字體的@font-face
聲明
解析文件URL,下載對應文件
Base64 編碼和內嵌內容作為 dataURL
連接所有已處理的 CSS 規則並將它們放入一個<style>
元素中,然後將其附加到克隆
嵌入影像
在<img>
元素中嵌入圖像 URL
background
CSS 屬性中使用的內嵌圖像,其方式類似於字體
將克隆的節點序列化為 XML
將 XML 包裝到<foreignObject>
標籤中,然後包裝到 SVG 中,然後將其設為資料 URL
或者,要取得 Uint8Array 形式的 PNG 內容或原始像素數據,請建立一個以 SVG 作為來源的 Image 元素,並將其渲染在您也建立的離螢幕畫布上,然後從畫布中讀取內容
完畢!
如果要渲染的 DOM 節點包含一個<canvas>
元素,並且在其上繪製了一些內容,則應該很好地處理它,除非畫布被污染 - 在這種情況下渲染將不會成功。
由於 dataURI 限制不同,在巨大 DOM 上渲染將失敗。
非常歡迎拉取請求和星星。
對於錯誤和功能請求,請建立問題。