整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          如何在 Java 中將 HTML 轉換為 PNG

          日分享最新,最流行的軟件開發知識與最新行業趨勢,希望大家能夠一鍵三連,多多支持,跪求關注,點贊,留言。

          本文討論了對 HTML 代碼可視化文檔的需求,并提供了一個免費的 API 解決方案,可將 HTML 字符串轉換為 PNG 屏幕截圖。

          自 20 世紀 80 年代后期的構想以來,超文本標記語言 (HTML) 一直是在線顯示網頁的關鍵元素。這種無處不在的編程語言繼續提供詳細的框架,用于構建我們在 Web 上看到和交互的內容,允許我們以純文本代碼格式化文本和多媒體組件,這很簡單,可以在需要時進行更改。
          HTML 的轉變
          與幾乎所有編程語言的情況一樣,HTML自推出以來的幾十年中已經轉變為包含許多新功能,以適應典型的當代壓力,例如社區反饋/批評和相鄰 Web 開發技術的快速發展。在現代 HTML 代碼的輸出中,我們可以很容易地看到這種轉換的結果;例如,最近的 HTML 迭代——HTML5,于 2014 年推出——提供了用于嵌入視頻和音頻文件的新的、簡單的元素,以及移動顯示和整體移動功能中急需的改進。

          當然,新元素和顯示質量的改進并不是網站的 HTML 代碼會隨著時間的推移可靠地改變的唯一原因。網站不斷設計和重新設計,可能是為了創新,也是為了響應用戶反饋產生的趨勢。例如,2014 年開發的網站很可能融合了各種當代設計趨勢,而與當年 HTML5 中引入的變化無關。在該項目之后的幾年里,該網站的開發人員可能會發現自己至少多次重復了他們的 HTML 代碼的一部分,同時一直在為不可避免的 HTML6 發布和最終合并其新的和改進的功能而構建。

          鑒于 HTML 開發中的這些自然進展,出現了一個重要問題:我們如何有效地跟蹤和記錄我們網站 HTML 代碼的增長?考慮到 HTML 輸出的固有視覺特性,答案相對簡單。我們可以輕松地以靜態二維圖像文件(屏幕截圖)的形式存儲 HTML 網站的迭代,并且我們可以相對輕松地以編程方式完成此轉換。

          網頁截圖
          捕獲 HTML 屏幕截圖具有大量實際的業務應用程序。當為網站編寫新的 HTML 代碼時,渲染該 HTML 代碼輸出的圖像作為一種簡單、易于共享的“狀態檢查”,用于檢查其內容在給定時間點如何顯示在 Web 瀏覽器上。出于同樣的原因,這樣的屏幕截圖提供了一種極好的方法來快速測試 HTML 代碼的新的、實驗性的迭代,使開發人員可以輕松地創建和存儲開發中項目的各種版本——包括成功的和不成功的。屏幕截圖還為實時網站中不可避免的問題提供了一種理想的可視化記錄方式,從而更容易跟蹤棘手的問題并跟蹤它們在不同設備、瀏覽器或操作系統上的顯示方式。

          教程
          本教程的目的是提供一個簡單、免費、易于使用的 API 解決方案,用于在 Java 中將 HTML 字符串轉換為 PNG 屏幕截圖。此 API 將完整呈現網站,返回 HTML 在常規 Web 瀏覽器視圖中顯示內容的屏幕截圖。它支持所有現代、高級的 Web 開發功能,包括與 HTML5、CSS、JavaScript等相關的功能。為方便起見,頁面下方提供了現成的 Java 代碼示例,以幫助您輕松構建 API 調用。

          該接口有兩個必填的請求參數,包括以下內容:

          你的 HTML 字符串
          一個免費的 Cloudmersive API 密鑰(您可以通過訪問我們的網站并注冊一個免費帳戶來獲得一個)。
          除了上述強制輸入外,此 API 還提供了幾個可選參數,允許進一步自定義您的輸入請求。這些可選參數包括以下內容:

          Extra loading wait:網頁完成加載后截屏前等待的額外毫秒數(對于非常異步的網站很有幫助)。
          屏幕截圖高度:屏幕截圖的所需高度,以像素表示(默認為 1280 x 1024)。提供整數“0”會觸發默認設置,而提供整數“-1”會要求 API 測量并嘗試屏幕高度屏幕截圖。
          屏幕截圖寬度:屏幕截圖的所需寬度,以像素表示(也默認為標準 1280 x 1024 測量值)。提供整數“0”或“-1”會產生與上述“屏幕截圖高度”參數中所述相同的結果。
          在其響應中,此 API 將提供一個包含新 PNG 文件編碼的字符串。

          要在Java中構建 API 調用,第一步是安裝 SDK。這可以使用 Maven 來完成,方法是首先將以下引用添加到存儲庫中pom.xml:

          <repositories>
          <repository>
          <id>jitpack.io</id>
          <url>https://jitpack.io</url>
          </repository>
          </repositories>



          之后,將下面的引用添加到依賴項中pom.xml:

          <dependencies>
          <dependency>
          <groupId>com.github.Cloudmersive</groupId>
          <artifactId>Cloudmersive.APIClient.Java</artifactId>
          <version>v4.25</version>
          </dependency>
          </dependencies>



          要改為使用 Gradle 安裝SDK,請在根目錄build.gradle(存儲庫末尾)中添加您的引用:

          allprojects {
          repositories {
          ...
          maven { url 'https://jitpack.io' }
          }
          }


          然后添加依賴項build.gradle:

          dependencies {
          implementation 'com.github.Cloudmersive:Cloudmersive.APIClient.Java:v4.25'
          }


          安裝完成后,剩下的就是復制并粘貼以下代碼示例,并完成如上所述的強制和可選請求參數:

          // Import classes:
          //import com.cloudmersive.client.invoker.ApiClient;
          //import com.cloudmersive.client.invoker.ApiException;
          //import com.cloudmersive.client.invoker.Configuration;
          //import com.cloudmersive.client.invoker.auth.*;
          //import com.cloudmersive.client.ConvertWebApi;

          ApiClient defaultClient = Configuration.getDefaultApiClient();

          // Configure API key authorization: Apikey
          ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
          Apikey.setApiKey("YOUR API KEY");
          // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
          //Apikey.setApiKeyPrefix("Token");

          ConvertWebApi apiInstance = new ConvertWebApi();
          HtmlToPngRequest input = new HtmlToPngRequest(); // HtmlToPngRequest | HTML to PNG request parameters
          try {
          byte[] result = apiInstance.convertWebHtmlToPng(input);
          System.out.println(result);
          } catch (ApiException e) {
          System.err.println("Exception when calling ConvertWebApi#convertWebHtmlToPng");
          e.printStackTrace();
          }


          一旦你完成了這一步,你就大功告成了——你現在可以調用這個 API 并輕松地將 HTML 字符串呈現為 PNG 屏幕截圖。

          注意: 您的免費層級 API 密鑰將提供每月 800 次 API 調用的限制,無需承諾。一旦達到該限制,您的總數將在下個月重置。

          需求一直有,今年比較多,如題,工作中遇到網頁截圖這樣的需求,本著效果好,功能全又穩定的意圖,去網上搜索相關技術,像HTML2Image、cssbox、selenium等,還有很多其他的技術,這篇文章主要說說我測試使用并能滿足需求的cssbox,selenium。

          Cssbox

          CSSBox是一個用純Java編寫的(X)HTML/CSS渲染引擎。它的主要目的是提供關于呈現的頁面內容和布局的完整和進一步可處理的信息。 但是,它也可以用于瀏覽Java Swing應用程序中呈現的文檔。核心CSSBox庫還可以用于獲得所呈現的文檔的位圖或矢量(SVG)圖像。 使用SwingBox包,CSSBox可以用作Java Swing應用程序中的交互式Web瀏覽器組件。

          官網地址:http://cssbox.sourceforge.net/

          使用

          1引入maven依賴

          <!--網站轉換為圖片cssbox-->
          <dependency>
          <groupId>net.sf.cssbox</groupId>
          <artifactId>cssbox</artifactId>
          <version>5.0.0</version>
          </dependency>

          2使用

          @Test
          public void cssboxTest(){
              try {
                  ImageRenderer render = new ImageRenderer();
                  //網絡鏈接的html
                  String url = "https://www.zhangbj.com/p/524.html";
                  //文件保存路徑
                  String path = "C:\\Users\\Administrator\\Desktop"+File.separator+"html.png";
                  FileOutputStream out = new FileOutputStream(new File(FilenameUtils.normalize(path)));
                  //開始截屏
                  render.renderURL(url, out);
              } catch (Exception e) {
              e.printStackTrace();
              }
          }

          3結果

          樣式可能出現問題,中文有時候亂碼

          Selenium

          1引入依賴

          <dependency>
          <groupId>org.seleniumhq.selenium</groupId>
          <artifactId>selenium-java</artifactId>
          <version>3.141.59</version>
          </dependency>

          2相關準備

          selenium+chromedriver谷歌驅動+chrome瀏覽器

          1.注意谷歌驅動的版本要和谷歌瀏覽器的版本一樣或者版本最相近

          2.注意chromedriver谷歌驅動需要放在jdk安裝目錄下,具體路徑為xxx/bin/chromedriver.exe,在linux和window中操作一樣,這樣切換系統是就無需改代碼。

          3.需要安裝谷歌瀏覽器

          谷歌驅動下載地址:https://registry.npmmirror.com/binary.html?path=chromedriver/

          3使用

          @Slf4j
          public class Html2ImageUtil {
          /**
          * 將HTML轉為圖片,并保存至指定位置
          * @param url 頁面地址
          * @param targetPath 保存地址(包含圖片名,如 /images/test.png)
          * @return
          */
          public static String htmlToImage(String url, String targetPath) {
            if (StringUtils.isEmpty(url) || StringUtils.isEmpty(targetPath)) {
            throw new RuntimeException("截圖失敗!缺少必填項");
            }
            // 休眠時長
            Integer sleepTime = 3 * 1000;
            // 無頭模式
            System.setProperty("java.awt.headless", "true");
            //獲取谷歌配置信息
            ChromeOptions chromeOptions = getChromeOptions();
            // 配置信息中有默認窗口大小,也可以單獨設置窗口大小
            chromeOptions.addArguments("--window-size=1920,6000");
            //創建webdriver 谷歌驅動
            WebDriver driver = new ChromeDriver(chromeOptions);
            //也可以通過如下方式設置窗口大小
            // Dimension dimension = new Dimension(1000, 30);
            // driver.manage().window().setSize(dimension);
            try {
              //加載頁面
              driver.get(url);
              //等待加載頁面
              Thread.sleep(sleepTime);
              //截屏
              File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
              //保存到指定位置
              FileUtils.copyFile(srcFile, new File(FilenameUtils.normalize(targetPath)));
            } catch (InterruptedException | IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
            } finally {
            driver.quit();
            }
            log.info("截圖成功!");
            return targetPath;
          }
          /**
          * 獲取chrome配置信息
          * 注意 chromedriver谷歌驅動需要放在jdk安裝目錄下,具體路徑為xxx/bin/chromedriver.exe ,在linux和window中操作一樣
          * @return
          */
          public static ChromeOptions getChromeOptions() {
              ChromeOptions options = new ChromeOptions();
              //獲取當前操作系統
              String os = System.getProperty("os.name");
              //獲取jdk安裝目錄,需要提前將谷歌驅動放進jdk的bin目錄下,在linux和window中操作一樣
              String sysPath = System.getProperty("java.home").replace("jre", "bin");
              String chromeDriver = sysPath + File.separator+"chromedriver.exe";
              options.addArguments("disable-infobars");
              //設置為 headless 模式,不需要真實啟動瀏覽器
              options.setHeadless(true);
              //options.addArguments("--headless");
              options.addArguments("--dns-prefetch-disable");
              options.addArguments("--no-referrers");
              options.addArguments("--disable-gpu");
              options.addArguments("--disable-audio");
              options.addArguments("--no-sandbox");
              options.addArguments("--ignore-certificate-errors");
              options.addArguments("--allow-insecure-localhost");
              options.addArguments("--window-size=1920,6000"); // 窗口默認大小
              String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36";
              userAgent = "user-agent=" + userAgent;
              options.addArguments(userAgent);
              // 設置chrome二進制文件
              options.setPageLoadStrategy(PageLoadStrategy.EAGER);
              // 設置驅動
              System.setProperty("webdriver.chrome.driver", chromeDriver);
              log.debug("結束獲取chrome配置信息");
              return options;
          }

          測試

          public static void main(String[] args) {
          		htmlToImage("https://www.cnblogs.com/tester-ggf/p/12602211.html","C:\\Users\\Administrator\\Desktop\\aaa.png");
          }

          效果十分完美

          總結

          最完美的方案就是selenium+chromedriver谷歌驅動+chrome瀏覽器,無需多說,用吧。

          您的贊和關注是對我創作的最大肯定謝謝大家!

          OM to Image

          dom-to-image是一個js庫,可以將任意dom節點轉換為矢量(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');

          用法

          所有高階函數都接受DOM節點和渲染選項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數組的形式獲取原始像素數據,每4個數組元素表示一個像素的RGBA數據:
          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參數

          Name

          類型

          Default

          Description

          filter

          Function

          ——

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

          bgcolor

          String

          ——

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

          height

          Number

          ——

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

          width

          Number

          ——

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

          style

          Object

          ——

          object對象,其屬性在渲染之前要復制到節點的樣式中。

          quality

          Number

          1.0

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

          cacheBust

          Boolean

          false

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

          imagePlaceholder

          Boolean

          undefined

          獲取圖片失敗時使用圖片的數據URL作為占位符。默認為未定義,并將在失敗的圖像上引發錯誤。

          原理

          dom-to-image使用SVG的一個特性,它允許在標記中包含任意HTML內容。

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

          部分源碼分析

          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設置默認options選項
          • domtoimage的核心api:
            • toSvg
            • toPng
            • toJpeg
            • toBlob
            • toPixelData
          • 例:toJpeg:將draw函數返回的canvas實例,使用canvas的toDataURL方法生成jpeg圖片。toSvg函數將遞歸地克隆原始DOM節點, 將克隆的節點序列化為XML,將XML包裝到標記中,然后包裝到SVG中,然后使其轉成dataURL。
          function toJpeg(node, options) {
             options = options || {};
             return draw(node, options)
                 .then(function (canvas) {
                     return canvas.toDataURL('image/jpeg', options.quality || 1.0);
                 });
          }
          復制代碼
          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


          主站蜘蛛池模板: 午夜无码一区二区三区在线观看| 亚洲AV无码一区二区三区电影| 波多野结衣中文一区二区免费| 无码人妻av一区二区三区蜜臀| 国产一区二区三区韩国女主播| 亚洲综合av一区二区三区| 亚洲AV日韩综合一区尤物| 精品视频一区在线观看| 中文字幕一区在线观看| 日韩免费一区二区三区在线播放| 国模视频一区二区| 亚洲熟女乱综合一区二区| 夜色福利一区二区三区| 国产精品资源一区二区 | 麻豆果冻传媒2021精品传媒一区下载| 爆乳无码AV一区二区三区| 99精品久久精品一区二区| 亚洲一区二区三区免费观看| 香蕉久久AⅤ一区二区三区| 亚洲av无码一区二区乱子伦as| 成人国产精品一区二区网站公司| 清纯唯美经典一区二区| 亚洲熟女www一区二区三区| 国产精品亚洲综合一区| 亚洲AV无码一区二区大桥未久| 日本亚洲国产一区二区三区| 国产乱码精品一区二区三区| 成人区精品人妻一区二区不卡| 国产精品视频一区国模私拍 | 日本免费电影一区| 在线视频一区二区| 国模丽丽啪啪一区二区| 大香伊蕉日本一区二区| 亚洲一区二区三区在线| 日本道免费精品一区二区| 波多野结衣一区二区免费视频| 中文字幕乱码人妻一区二区三区| 丝袜人妻一区二区三区| 色视频综合无码一区二区三区| 无码中文字幕人妻在线一区二区三区 | 麻豆一区二区在我观看|