整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          "一鍵將網(wǎng)頁截圖制作成HTML網(wǎng)頁"

          尋找熱愛表達(dá)的你#


          "一鍵將網(wǎng)頁截圖制作成HTML網(wǎng)頁"是指一種技術(shù),它允許用戶通過簡單的操作,將網(wǎng)頁的截圖轉(zhuǎn)換成HTML代碼的網(wǎng)頁。這通常涉及到自動布局、樣式提取和代碼生成。以下是實現(xiàn)這一功能的相關(guān)技術(shù)和步驟:

          1. 截圖捕捉:首先,需要有一個方法來捕捉網(wǎng)頁的截圖,這可以通過瀏覽器插件、屏幕捕獲工具或?qū)iT的應(yīng)用程序來完成。

          2. 圖像處理:捕捉到的截圖可能需要進(jìn)行預(yù)處理,比如裁剪、壓縮或調(diào)整分辨率,以確保圖像的質(zhì)量。

          3. 元素識別:使用圖像識別技術(shù)來分析截圖,識別網(wǎng)頁中的元素,比如文本、按鈕、圖片等。

          4. 布局分析:基于識別出的元素,分析頁面的布局信息,包括元素的大小、位置和層級。

          5. 樣式解析:提取頁面的樣式信息,包括顏色、字體、間距等,并將它們轉(zhuǎn)換為CSS代碼。

          6. HTML生成:根據(jù)布局和樣式信息,生成HTML結(jié)構(gòu)代碼,將截圖中的元素轉(zhuǎn)換為HTML標(biāo)簽。

          7. 代碼優(yōu)化:對生成的HTML代碼進(jìn)行優(yōu)化,確保代碼的可讀性、維護(hù)性和性能。

          8. 響應(yīng)式設(shè)計:確保生成的網(wǎng)頁代碼能夠適應(yīng)不同的屏幕尺寸和設(shè)備,實現(xiàn)響應(yīng)式布局。

          9. 交互性實現(xiàn):如果截圖中的頁面包含交互元素,需要添加相應(yīng)的JavaScript代碼來實現(xiàn)這些交互。

          10. 一鍵操作:提供一個簡單的用戶界面,用戶只需點擊一個按鈕,就可以完成截圖到HTML的轉(zhuǎn)換。

          11. 預(yù)覽功能:在轉(zhuǎn)換過程中提供實時預(yù)覽,讓用戶可以實時看到轉(zhuǎn)換效果。

          12. 自定義選項:允許用戶對生成的HTML代碼進(jìn)行自定義,比如修改布局、添加額外的樣式或功能。

          13. 保存和導(dǎo)出:用戶可以保存或?qū)С錾傻腍TML代碼,以便進(jìn)一步使用或分享。

          14. 錯誤處理:在轉(zhuǎn)換過程中識別和處理潛在的錯誤,比如布局沖突或樣式問題。

          15. 兼容性測試:確保生成的網(wǎng)頁在不同的瀏覽器和設(shè)備上都能正常顯示和工作。

          16. 安全性考慮:生成的代碼應(yīng)遵循安全最佳實踐,避免潛在的安全風(fēng)險。

          17. 用戶反饋:收集用戶反饋,不斷改進(jìn)轉(zhuǎn)換算法和用戶體驗。

          18. 開源和社區(qū)支持:作為開源項目,鼓勵社區(qū)參與貢獻(xiàn)代碼和改進(jìn)功能。

          這種一鍵轉(zhuǎn)換技術(shù)可以大大提高網(wǎng)頁開發(fā)的效率,尤其是對于快速原型設(shè)計和演示目的。然而,需要注意的是,自動生成的代碼可能需要進(jìn)一步的人工審查和調(diào)整,以確保最終產(chǎn)品的質(zhì)量和性能。此外,一些復(fù)雜的網(wǎng)頁效果和動態(tài)交互可能需要手動編寫代碼來實現(xiàn)。

          OM to Image

          dom-to-image是一個js庫,可以將任意dom節(jié)點轉(zhuǎn)換為矢量(SVG)或光柵(PNG或JPEG)圖像。

          安裝

          npm install dom-to-image -S

          加載

          /* in ES 6 */
          import domtoimage from 'dom-to-image';
          /* in ES 5 */
          var domtoimage = require('dom-to-image');

          用法

          所有高階函數(shù)都接受DOM節(jié)點和渲染選項options ,并返回promises。

          1. 獲取PNG圖像base64編碼的data URL:
          <div id="my-node"></div>
          var node = document.getElementById('my-node');
          // options 可不傳
          var options = {}  
          domtoimage.toPng(node, options)
              .then(function (dataUrl) {
                  var img = new Image();
                  img.src = dataUrl;
                  document.body.appendChild(img);
              })
              .catch(function (error) {
                  console.error('oops, something went wrong!', error);
              });
          1. 獲取圖像blob:
          domtoimage.toBlob(document.getElementById('my-node'))
              .then(function (blob) { 
                  console.log('blob', blob)
              });
          1. 獲取JPEG圖像base64編碼的data URL并下載:
          domtoimage.toJpeg(document.getElementById('my-node'), { quality: 0.95 })
              .then(function (dataUrl) {
                  var link = document.createElement('a');
                  link.download = 'my-image-name.jpeg';
                  link.href = dataUrl;
                  link.click();
          });
          1. 獲取SVGdata URL,但篩選出所有元素:
          function filter (node) {
              return (node.tagName !== 'i');
          }
           
          domtoimage.toSvg(document.getElementById('my-node'), {filter: filter})
              .then(function (dataUrl) {
                  /* do something */
          });
          1. 以uint8數(shù)組的形式獲取原始像素數(shù)據(jù),每4個數(shù)組元素表示一個像素的RGBA數(shù)據(jù):
          var node = document.getElementById('my-node');
           
          domtoimage.toPixelData(node)
              .then(function (pixels) {
                  for (var y = 0; y < node.scrollHeight; ++y) {
                    for (var x = 0; x < node.scrollWidth; ++x) {
                      pixelAtXYOffset = (4 * y * node.scrollHeight) + (4 * x);
                      /* pixelAtXY is a Uint8Array[4] containing RGBA values of the pixel at (x, y) in the range 0..255 */
                      pixelAtXY = pixels.slice(pixelAtXYOffset, pixelAtXYOffset + 4);
                    }
                  }
              });

          options參數(shù)

          Name

          類型

          Default

          Description

          filter

          Function

          ——

          以DOM節(jié)點為參數(shù)的函數(shù)。如果傳遞的節(jié)點應(yīng)包含在輸出中,則應(yīng)返回true(排除節(jié)點意味著也排除其子節(jié)點)

          bgcolor

          String

          ——

          背景色的字符串值,任何有效的CSS顏色值。

          height

          Number

          ——

          渲染前應(yīng)用于節(jié)點的高度(以像素為單位)。

          width

          Number

          ——

          渲染前應(yīng)用于節(jié)點的寬度(以像素為單位)。

          style

          Object

          ——

          object對象,其屬性在渲染之前要復(fù)制到節(jié)點的樣式中。

          quality

          Number

          1.0

          介于0和1之間的數(shù)字,表示JPEG圖像的圖像質(zhì)量(例如0.92=>92%)。默認(rèn)值為1.0(100%)

          cacheBust

          Boolean

          false

          設(shè)置為true可將當(dāng)前時間作為查詢字符串附加到URL請求以啟用清除緩存。

          imagePlaceholder

          Boolean

          undefined

          獲取圖片失敗時使用圖片的數(shù)據(jù)URL作為占位符。默認(rèn)為未定義,并將在失敗的圖像上引發(fā)錯誤。

          原理

          dom-to-image使用SVG的一個特性,它允許在標(biāo)記中包含任意HTML內(nèi)容。

          • 遞歸地克隆原始DOM節(jié)點
          • 計算節(jié)點和每個子節(jié)點的樣式,并將其復(fù)制到相應(yīng)的克隆 創(chuàng)建偽元素,因為它們不是以任何方式克隆的
          • 嵌入web字體 查找所有@font face聲明的web字體 解析文件URL,下載相應(yīng)文件 base64編碼的內(nèi)聯(lián)作為data:URLs 將所有已處理的CSS放入中,然后將其附加到克隆
          • 嵌入圖片 在嵌入圖片URL 使用backgroundCSS屬性的圖片,方法類似于字體
          • 將克隆的節(jié)點序列化為XML
          • 將XML包裝到標(biāo)記中,然后包裝到SVG中,然后使其成為data URL
          • 或者,要以Uint8Array的形式獲取PNG內(nèi)容或原始像素數(shù)據(jù),可以創(chuàng)建一個以SVG為源的圖像元素,并將其呈現(xiàn)在已經(jīng)創(chuàng)建的canvas上,從canvas讀取內(nèi)容

          部分源碼分析

          dom-to-image.js

          // Default impl options
          var defaultOptions = {
              // Default is to fail on error, no placeholder
              imagePlaceholder: undefined,
              // Default cache bust is false, it will use the cache
              cacheBust: false
          };
          
          var domtoimage = {
              toSvg: toSvg,
              toPng: toPng,
              toJpeg: toJpeg,
              toBlob: toBlob,
              toPixelData: toPixelData,
              impl: {
                  fontFaces: fontFaces,
                  images: images,
                  util: util,
                  inliner: inliner,
                  options: {}
              }
          };
          
          if (typeof module !== 'undefined')
              module.exports = domtoimage;
          else
              global.domtoimage = domtoimage;
          • defaultOptions設(shè)置默認(rèn)options選項
          • domtoimage的核心api:
            • toSvg
            • toPng
            • toJpeg
            • toBlob
            • toPixelData
          • 例:toJpeg:將draw函數(shù)返回的canvas實例,使用canvas的toDataURL方法生成jpeg圖片。toSvg函數(shù)將遞歸地克隆原始DOM節(jié)點, 將克隆的節(jié)點序列化為XML,將XML包裝到標(biāo)記中,然后包裝到SVG中,然后使其轉(zhuǎn)成dataURL。
          function toJpeg(node, options) {
             options = options || {};
             return draw(node, options)
                 .then(function (canvas) {
                     return canvas.toDataURL('image/jpeg', options.quality || 1.0);
                 });
          }
          復(fù)制代碼
          function draw(domNode, options) {
              return toSvg(domNode, options)
                  .then(util.makeImage)
                  .then(util.delay(100))
                  .then(function (image) {
                      var canvas = newCanvas(domNode);
                      canvas.getContext('2d').drawImage(image, 0, 0);
                      return canvas;
                  });
          
              function newCanvas(domNode) {
                  var canvas = document.createElement('canvas');
                  canvas.width = options.width || util.width(domNode);
                  canvas.height = options.height || util.height(domNode);
          
                  if (options.bgcolor) {
                      var ctx = canvas.getContext('2d');
                      ctx.fillStyle = options.bgcolor;
                      ctx.fillRect(0, 0, canvas.width, canvas.height);
                  }
          
                  return canvas;
              }
          }
          function toSvg(node, options) {
              options = options || {};
              copyOptions(options);
              return Promise.resolve(node)
                  .then(function (node) {
                      return cloneNode(node, options.filter, true);
                  })
                  .then(embedFonts)
                  .then(inlineImages)
                  .then(applyOptions)
                  .then(function (clone) {
                      return makeSvgDataUri(clone,
                          options.width || util.width(node),
                          options.height || util.height(node)
                      );
                  });
          
              function applyOptions(clone) {
                  if (options.bgcolor) clone.style.backgroundColor = options.bgcolor;
          
                  if (options.width) clone.style.width = options.width + 'px';
                  if (options.height) clone.style.height = options.height + 'px';
          
                  if (options.style)
                      Object.keys(options.style).forEach(function (property) {
                          clone.style[property] = options.style[property];
                      });
          
                  return clone;
              }
          }


          作者:知其
          https://juejin.cn/post/6988045156473634852

          條APP上有個截圖分享功能,就是把文章轉(zhuǎn)成一張圖片,然后分享到各渠道中去,如微信、QQ等,非常實用,因此,打算就這項功能自己封裝為一個組件ImageGenerator,后期專門進(jìn)行圖片生成,html是其中的一個源。


          頭條截圖分享的實際效果圖


          目前前端使用較多的html轉(zhuǎn)圖片的工具是Html2Canvas,考慮技術(shù)儲備和問題討論的充裕性,決定封裝一下這個工具。步驟如下:


          安裝HTML2Canvas

          按照官方要求,做安裝操作:

          npm

          npm install html2canvas


          我當(dāng)時下載的是1.4.1的版本。



          這個工具有自身的一些限制,使用時要注意:

          [1] 并非真正的截圖軟件,而是根據(jù)DOM繪制出來的,其繪制能力,完全依賴于工具對DOM和對應(yīng)屬性的支持和理解;

          [2] 因為使用了Canvas支持,生成圖片的區(qū)域不能再有Canvas應(yīng)用,否則會干擾工具的生成,不能保證生成預(yù)期,因此,如果使用了Canvas圖表的應(yīng)用這個工具不推薦使用


          封裝ImageGenerator

          這個很簡單,這里就是封裝一個組件,用于后期引入html之外的源生成圖片,同時也做一下圖片的統(tǒng)一顯示,從而和系統(tǒng)整體的設(shè)計進(jìn)行配合。大致的實現(xiàn)思路如下:



          上圖,我們引入了工具本身,并設(shè)置的結(jié)果的顯示區(qū)。生成的結(jié)果將以節(jié)點的方式注入 #image-box 中。


          上圖,封裝了一個方法,用途是利用Html2Canvas工具獲得圖片,這里我們引入了一個組件的數(shù)據(jù)imageData用以存儲和干預(yù)生成結(jié)果。在這里,我把ImageGenerator封裝為全局組件。


          應(yīng)用場景

          我們在文章的尾部加入一個share功能,點擊彈出分享設(shè)置的彈窗,實際效果如下圖所示:




          以上技術(shù)實現(xiàn)比較簡單,這里就不進(jìn)行贅述了。上圖中,我們設(shè)置了一個生成圖像按鈕,點擊該按鈕則可以觸發(fā)我們組件中的對應(yīng)操作。關(guān)鍵思路包括:

          【1】這里設(shè)置了一個封裝組件shareHandler,封裝了前導(dǎo)模塊和imageGenerator,這兩個模塊的顯示通過一個開關(guān)進(jìn)行控制,該開關(guān)則通過圖像生成成功事件進(jìn)行賦值,這樣的話,我們可以實現(xiàn)圖片生成后,不再顯示前導(dǎo)模塊,而是顯示圖片結(jié)果,即ImageGenerator。


          【2】這里有一個比較關(guān)鍵的操作是shareHandler通過觸發(fā)事件將轉(zhuǎn)換器發(fā)射到文章轉(zhuǎn)換現(xiàn)場,為什么用事件,還是那句話,事件對于解耦和消除組件依賴是最自然的實現(xiàn)。注意,這里我把imageGenerator通過引用的方式作為參數(shù)傳出了,這樣的好處是事件將轉(zhuǎn)換器代入了轉(zhuǎn)換現(xiàn)場,并可以攜帶回現(xiàn)場轉(zhuǎn)換結(jié)果。



          【3】在文章查看器,solutionViewer中,自然會訂閱事件、事件處理和取消訂閱。注意這里的事件處理,實際上是調(diào)用了轉(zhuǎn)換器中我們封裝的函數(shù),參數(shù)則是現(xiàn)場取得的,這里的機(jī)制很簡單,定義要轉(zhuǎn)換div的id,作為參數(shù)傳入函數(shù)。



          那么,點擊圖像后,我們可以看到效果圖:



          點擊右鍵另存圖像,我們可以獲得一張png格式的圖片,至于后續(xù)對下載和到粘貼板的支持,大家可以自行研究和實現(xiàn)。



          注意事項

          實現(xiàn)過程中有幾個注意事項:

          【1】Canvas返回時,其長寬都是按照實際大小生成的,而我們的例子中,則要根據(jù)右抽屜式的彈窗做width=100%,height=auto的處理,這個要如何實現(xiàn),就是要通過我們在imageGenerator中引入的imageData。


          【2】我們的文章顯示中,引入了文件管理的微服務(wù),因此,文章中圖片的鏈接都是跨域的,所以,必須打開html2Canvas的跨域選項,在封裝的組件里,我是通過一共一個defaultOptions來實現(xiàn)這一點的。



          這個選項可以在轉(zhuǎn)換場景提供,也可提供一系列的默認(rèn)值,最常用的除跨域外,還有是否允許log輸出等開關(guān),大家感興趣可以自行查閱html2Canvas的官網(wǎng)。


          內(nèi)容比較簡單,大家如果有這個應(yīng)用場景,可以參考實現(xiàn)一下,有問題歡迎大家隨時交流。謝謝大家的支持。


          主站蜘蛛池模板: 一区二区三区电影在线观看| 精品一区二区三区免费毛片 | 国产一区二区精品| 麻豆一区二区在我观看| 高清一区二区在线观看| 日韩人妻精品一区二区三区视频 | 亚洲国产精品乱码一区二区| 国产成人精品日本亚洲专一区| 国产精品视频一区麻豆| 中文字幕一区二区三区在线播放 | 中文字幕一区二区日产乱码| 久久精品无码一区二区三区日韩 | 精品国产高清自在线一区二区三区| 一区二区三区午夜| 国产一区二区三区夜色| 国产福利电影一区二区三区| 午夜DV内射一区区| 伦理一区二区三区| 国产精品成人免费一区二区 | 一本一道波多野结衣AV一区| 亚洲一区免费观看| 美女一区二区三区| 国产精品一级香蕉一区| 在线欧美精品一区二区三区| AV鲁丝一区鲁丝二区鲁丝三区| 精品国产乱子伦一区二区三区| 老熟女五十路乱子交尾中出一区| 亚洲国产一区国产亚洲| 亚洲国产精品一区二区成人片国内| 曰韩人妻无码一区二区三区综合部| 色窝窝无码一区二区三区色欲| 丰满岳乱妇一区二区三区| 久久国产午夜精品一区二区三区| 精品熟人妻一区二区三区四区不卡| 国产福利91精品一区二区| 国产精品乱码一区二区三| 在线视频一区二区三区三区不卡| 国产视频一区二区在线播放| 99精品久久精品一区二区| 精品人妻少妇一区二区三区不卡| 日韩在线视频一区|