透過JavaScript將HTML轉為圖檔

最近寫了小工具用ASP.NET MVC及Knockout讀取跑道計圈GPS資料轉成HTML表格,當成運動記錄的圖檔附件,但每次產生HTML表格後都得用螢幕擷取工具將網頁畫面另存圖檔,雖然手續還算單純,但你知道,懶惰是沒有極限的,我開始動腦筋,打算將產生圖檔的動作也自動化。

薑薑薑薑~ 如上圖所示,真的被我找到方法! 一切要感謝神奇的程式庫—html2canvas,它可以將整張網頁或局部元素轉為HTML5 Canvas,一旦轉成Canvas,匯出圖檔便是小事一椿囉!

html2canvas的原理並非擷取網頁畫素,而是解析DOM及CSS的所有細節,在HTML5 Canvas裡以線、矩形、圓弧、文字... 等試著模擬出相同外觀,因此產出結果可能有細微誤差,也存在無法讀取跨網域內容的限制,但經實際使用,效果已讓人滿意,html2canvas幾乎是用Canvas打造出靜態網頁瀏覽器引擎,是神人級的作品。(咦? 我怎麼跪著寫範例程式... )

範例程式碼如下,有興趣的朋友也可試玩看看:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>HTML to Image</title>
  <style>
    table { background-color: #ccddff; }
    td { padding: 2px 6px; }
    table input { 
      width: 100px; padding: 2px 6px; 
      color: blue; border: 1px solid gray; 
    }
    fieldset { width: 200px; height: 120px; margin-top: 6px; }
  </style>
</head>
<body>
  <table>
    <tr><td>姓名</td><td><input value="Darkthread"></td></tr>
    <tr><td>積分</td><td><input value="9999"></td></tr>
  </table>
  <hr />
  <input type="button" value="轉為圖檔" />
  <a></a>
  <fieldset>
    <legend>圖檔</legend>
    <div>
    </div>
  </fieldset>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js "></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js "></script>
<script src="http://html2canvas.hertzen.com/build/html2canvas.js"></script>
  <script>
    $(":button").click(function() {
      html2canvas($("table")[0], {
        onrendered: function(canvas) {
          var $div = $("fieldset div");
          $div.empty();
          $("<img />", { src: canvas.toDataURL("image/png") }).appendTo($div);
        }
      });
    });
  </script>
</body>
</html>
歡迎推文分享:
Published 09 April 2014 10:41 PM 由 Jeffrey
Filed under:
Views: 24,077



意見

# Randolph said on 10 April, 2014 11:58 AM

我今天研究了上傳圖片檔時先在瀏覽器 Resize 再上傳檔案的程式碼。

它會用到你最近使用的 Canvas 及相關 HTML5 新物件。

應該蠻適合你最近對於 HTML5 的研究,不知道你有沒有興趣研究看看。

# 小胖 said on 15 May, 2014 09:06 PM

我有興趣 @@"

# 小孟 said on 20 August, 2015 11:27 PM

請問有辦法直接執行PAGE時就變成圖檔嗎?

# Jeffrey said on 21 August, 2015 01:23 AM

to 小孟, 不明白「直接執行PAGE時就變成圖檔」的定義,需要再進一步解釋。

# 豆沙包 said on 27 May, 2016 04:28 AM

想請問  這個可以調整儲存圖片的解析度嗎??

我們儲存以後列印出來解析度不夠

文字都有點糊糊的

想請問該怎樣解決

# Jeffrey said on 27 May, 2016 05:00 PM

to 豆沙包,html2canvas基本上是用螢幕的解析度產生圖檔,與列印的理想解析度有段距離(96DPI vs 300DPI),針對這問題github有一串討論( github.com/.../241 ),有人想到用CSS把網頁放大N倍再匯出成圖檔的解決方案,你可以參考看看。

# danny said on 13 January, 2017 02:48 AM

請問:

html2canvas($("table")[0]這裡我有看懂是把table中的都輸出,想說說,如果我有很多div要分開來輸出是否可以?

例如:

<div class="a">文字1</div>

<div class="a">文字2</div>

<div class="a">文字3</div>

我試著改成html2canvas($(".a"))....都只會把"文字1"變圖而已,"文字2"之後的就不行了,

請問有解嗎? ^__^

# Jeffrey said on 13 January, 2017 09:40 AM

to danny, 應寫成 $(".a").each(function() { html2canvas(this, ....); }); 範例:http://output.jsbin.com/hifibi

# danny said on 15 January, 2017 08:55 PM

Jeffery 感謝解惑 ^_^,

再請問,

例如:

<div class="a">文字1</div>

<div class="b">文字2</div>

<div class="b">文字3</div>

只要是class="a"的div中"文字1"就直接變圖,

這是否可行?

# Jeffrey said on 16 January, 2017 08:28 PM

to danny, 不太理解「只要是class="a"的div中"文字1"就直接變圖」,需要更完整的說明才能幫忙。

# danny said on 18 January, 2017 10:11 AM

Sorry Jeffrey 沒講清楚 @_@,

假設頁面中會有很多個class="a"的div,

但都在不同的位置

1. <div class="a">想變圖的字</div>

2. <div class="b">一般文字</div>

3. <div class="a">想變圖的字</div>

只要是被class="a" div包住的內容都會輸出成圖,

再請解惑了~

# Jeffrey said on 18 January, 2017 10:33 AM

to danny, http://jsbin.com/jebibu 你的需求一樣寫$(".a").each(…) 即可,程式不需修改。

# danny said on 19 January, 2017 02:05 AM

Jeffrey 感謝熱心的協助且解惑,

真得獲益良多 @_^~

# Jim said on 20 March, 2017 09:11 PM

我想問一下 我出的同時想把圖片等比例放大會有辦法做到麼

例如我的div尺寸為 640*360想輸出時為1280*720

第二個問題是 我想在IE8也使用此功能有甚麼方法麼?

# Jeffrey said on 21 March, 2017 08:55 AM

to Jim, 直接放大圖檔會產生鋸齒,我建議放大 div 尺寸再用放大後的 div 轉圖檔效果會較好。IE8 不支援 HTML5 Canvas,非做不可的話要依賴 Flash、Java Applet、Silverlight、ActiveX…,但這堆都算過時技術,現階段再投入研究不符效益,建議慎重評估。

# ThankU said on 08 April, 2017 09:13 PM

請問, 如何直接把產出的圖存檔?

# Jeffrey said on 10 April, 2017 01:30 AM

to ThankU, 請參考這篇:blog.darkthread.net/post-2011-10-30-html5-canvas-sktechpad.aspx

# Ricky said on 04 May, 2017 09:49 PM

radio 變成圖片的時候是空白的

有辦法解決嗎

# Jeffrey said on 05 May, 2017 04:43 AM

to Ricky, 能否提供jsbin範例重現問題?

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<April 2014>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication