html生成縮略圖來預覽解決方案

html生成縮略圖來預覽解決方案

1、總結

一句話總結:先將html轉化爲canvas,而後將canvas生成圖片ajax上傳到服務器,就能夠了

html 轉化 canvas 圖片 上傳 html2canvas.js

 

一、如何將html轉化爲canvas?

SVG foreignObject元素
html2canvas.js

首先咱們不能直接把 HTML 畫到 canvas 上。咱們須要使用一個SVG 圖像包含想要呈現的內容 。爲了繪製 HTML 內容,你要先用<foreignObject> 元素包含 HTML 內容,而後再將這個 SVG 圖像繪製到你的 canvas 中。css

這裏的foreignObject元素容許包含外來的XML命名空間,其圖形內容是別的用戶代理繪製的。這個被包含的外來圖形內容服從SVG變形和合成。html

咱們轉化的步驟爲:
1. 建立一個blob 對象, 其 MIME 應爲 「image/svg+xml」。
2. 一個 <svg> 元素。
3. 在 SVG 元素中包含的 <foreignObject> 元素。
4. 包裹到 <foreignObject> 中的(格式化好的) HTML。es6

 

也能夠直接用框架,效果更好。html2canvas.js。web

 

 

二、canvas轉化爲圖片的框架?

Canvas2Image.js

其實你想實現什麼效果,好比canvas轉化爲圖片的js,直接google百度上面一搜就好,一大堆ajax

 

2、HTML如何轉化爲canvas教程

預覽圖

老規矩, 先放圖canvas

這裏寫圖片描述

第一個紅格子是DOM渲染的, 第二個帶邊框的紅格子是用html的代碼在canvas畫出來的, 沒有使用canvas的api哦. 本文最後貼出了代碼.api

原理

本文轉化的實現, 以及本文下半部分所介紹的html2canvas.js框架的原理均出自於, mdn的這個篇文章將 DOM 對象繪製到 canvas 中
跨域

首先咱們不能直接把 HTML 畫到 canvas 上。咱們須要使用一個SVG 圖像包含想要呈現的內容 。爲了繪製 HTML 內容,你要先用<foreignObject> 元素包含 HTML 內容,而後再將這個 SVG 圖像繪製到你的 canvas 中。promise

這裏的foreignObject元素容許包含外來的XML命名空間,其圖形內容是別的用戶代理繪製的。這個被包含的外來圖形內容服從SVG變形和合成。瀏覽器

咱們轉化的步驟爲:
1. 建立一個blob 對象, 其 MIME 應爲 「image/svg+xml」。
2. 一個 <svg> 元素。
3. 在 SVG 元素中包含的 <foreignObject> 元素。
4. 包裹到 <foreignObject> 中的(格式化好的) HTML。

第一步預覽圖的代碼

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div class="wrapper">
    <div class="target" style=" width: 100px; height: 100px; background: red; margin-bottom: 50px; ">123</div>
  </div>

  <canvas id="canvas" style="border:2px solid black;" width="200" height="200">
  </canvas>

<script> let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); let target = document.getElementsByClassName('wrapper'); // 創造svg let data = ` <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <foreignObject width="100%" height="100%"> <div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px"> ${target[0].innerHTML} </div> </foreignObject> </svg> ` let DOMURL = window.URL || window.webkitURL || window; let img = new Image(); let svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); let url = DOMURL.createObjectURL(svg); // 根據svg生產url img.onload = function () { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); // 摧毀剛剛生產的url }// 註冊回調函數 img.src = url; // 將圖片url塞到img裏 </script>


</body>
</html>

有幾個須要注意的點:
1. 此方法中插入的html必須是有效的html
2. 必須使用內聯樣式, 而且支持部分樣式,
3. 已訪問的連接樣式(:visited)不會對 SVG 圖像中的連接生效,所以沒法獲取瀏覽歷史;SVG 圖像中也不會渲染原生主題,所以藉此檢測用戶的平臺也會更困難。
4. 此外,您也不能在 SVG 圖像中各類引入腳本文件,所以不會有從其餘腳本文件訪問 DOM 的風險。SVG 圖像中的 DOM 元素也不能接收事件的輸入,所以沒法將敏感信息載入到一個表單控件(如將完整路徑載入到 file <input> 元素中)渲染再經過讀取圖像獲取這些信息。
5. 這個解決方案所依賴的 SVG 圖像在實現上是很是嚴格的。若是引入了外部的圖片會污染canvas畫布. 可是接下來講介紹的html2canvas能夠解決這個問題!!!


html2canvas

框架官網地址: http://html2canvas.hertzen.com/
本文使用介紹基於1.0.0-alpha.12版本

效果圖

這裏寫圖片描述

此次直接有框架生成的canvas, 所以沒有了邊框. 下面是代碼

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style> .target { width: 100px; height: 100px; background: red; margin-bottom: 50px; } </style>
</head>
<body>
  <div class="wrapper">
    <div class="target">123</div>
  </div>

<script src="./canvas.js"></script>
<script> window.onload = function() { html2canvas(document.querySelector(".wrapper")).then(canvas => { document.body.appendChild(canvas) }); } </script>
</body>
</html>

.then是promise語法, 不瞭解es6的同窗能夠看看阮一峯es6入門, 寫的很是好.

上面的代碼能夠看到, 支持內聯樣式了, 同時使用起來也很簡單. 那麼上文所留下的懸念: 如何加載外部圖片呢? 接下來將會和html2canvas的配置項一塊兒介紹給你們.

html2canvas配置項

名稱 默認 描述
async true 是否異步解析和渲染元素
allowTaint false 是否容許跨原始圖像污染畫布
backgroundColor ffffff 畫布背景顏色
canvas null 你本身提供一個canvas用做繪圖, 此項不填框架會自動生成一個canvas標籤
foreignObjectRendering false 就是是否用上面所提到的foreignObject這個來渲染, 默認爲遍歷dom樹
imageTimeout 15000 設置圖像加載的超時時間(以毫秒爲單位)設置0爲禁用超時
ignoreElements (element) => false Predicate function which removes the matching elements from the render. 大體的意思是匹配元素, 在你渲染的時候去掉那個匹配的元素
logging true 啓用日誌記錄以進行調試
onclone null Callback function which is called when the Document has been cloned for rendering, can be used to modify the contents that will be rendered without affecting the original source document.這個我也不知道是幹嗎的, 歡迎你們踊躍提出建議
proxy null 填寫url, 設置代理,用於加載跨源圖像. 若是爲null,跨域圖片則不會加載
removeContainer true Whether to cleanup the cloned DOM elements html2canvas creates temporarily(還得研究, 不知道那個cloned DOM是幹嗎的)
scale window.devicePixelRatio 設置渲染的比例。默認爲瀏覽器設備像素比率
useCORS false 是否嘗試使用CORS從服務器加載圖像
width   canvas寬度
height   canvas高度
X Element x偏移量  
y Element y偏移量  

開啓圖片跨域

效果圖

這裏寫圖片描述

圖片隨便在網上找的

代碼

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style> img { width: 500px; } </style>
</head>
<body>
  <div class="wrapper">
    <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1533212152031&di=f26250570f7d5f2e7895c7c13e96d61a&imgtype=0&src=http%3A%2F%2Fh.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F267f9e2f07082838304837cfb499a9014d08f1a0.jpg"></img>
  </div>



<script src="./canvas.js"></script>
<script> window.onload = function() { html2canvas(document.querySelector(".wrapper"), { allowTaint: true, useCORS: true, }).then(canvas => { document.body.appendChild(canvas) }); } </script>


</body>
</html>

ps: 若是在小瓶圖片變糊, 能夠試着設置那個scale參數, 或者採用在canvas的width屬性設置例如1000, 在css中設置width: 500px; 來進行壓縮

若是你須要保存爲本地圖片能夠採用Canvas2Image.js這個框架, 具體內容百度, 本文不作介紹

 

參考:HTML如何轉化爲canvas教程 - 翾的博客 - CSDN博客https://blog.csdn.net/c_kite/article/details/81364592

相關文章
相關標籤/搜索