最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java利用Phantomjs實現(xiàn)生成圖片的功能

 更新時間:2020年08月01日 11:06:08   作者:王心森  
這篇文章主要介紹了Java利用Phantomjs實現(xiàn)生成圖片的功能,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下

今天,給大家分享一個Java后端利用Phantomjs實現(xiàn)生成圖片的功能,同學們使用的時候,可以參考下!

PhantomJS簡介

首先,什么是PhantomJS?

根據(jù)官網(wǎng)介紹:

PhantomJS is a command-line tool. -- 其實就是一個命令行工具。

PhantomJS的下載地址:

Windows:phantomjs-2.1.1-windows.zip

Linux:phantomjs-2.1.1-linux-x86_64.tar.bz2;phantomjs-2.1.1-linux-i686.tar.bz2

MacOS:phantomjs-2.1.1-macosx.zip

下載下來后,我們看到bin目錄下就是可執(zhí)行文件phantomjs.exe,我們可以將它配置到環(huán)境變量中,方便命令使用!

還有一個examples目錄,它下面是很多js樣例,關(guān)于這些樣例作用,參考官網(wǎng)解釋,給大家做個簡單翻譯:

1. Basic examples

  • arguments.js:顯示傳遞給腳本的參數(shù)
  • countdown.js:打印10秒倒計時
  • echoToFile.js:將命令行參數(shù)寫入文件
  • fibo.js:列出了斐波那契數(shù)列中的前幾個數(shù)字
  • hello.js:顯示著名消息
  • module.js:并universe.js演示模塊系統(tǒng)的使用
  • outputEncoding.js:顯示各種編碼的字符串
  • printenv.js:顯示系統(tǒng)的環(huán)境變量
  • scandir.js:列出目錄及其子目錄中的所有文件
  • sleepsort.js:對整數(shù)進行排序并根據(jù)其值延遲顯示
  • version.js:打印出PhantomJS版本號
  • page_events.js:打印出頁面事件觸發(fā):有助于更好地掌握page.on*回調(diào)

2. Rendering/rasterization

  • colorwheel.js:使用HTML5畫布創(chuàng)建色輪
  • rasterize.js:將網(wǎng)頁光柵化為圖像或PDF
  • render_multi_url.js:將多個網(wǎng)頁渲染為圖像

3. Page automation

  • injectme.js:將自身注入到網(wǎng)頁上下文中
  • phantomwebintro.js:使用jQuery從phantomjs.org讀取.version元素文本
  • unrandomize.js:在頁面初始化時修改全局對象
  • waitfor.js:等待直到測試條件為真或發(fā)生超時

4. Network

  • detectniff.js:檢測網(wǎng)頁是否嗅探用戶代理
  • loadspeed.js:計算網(wǎng)站的加載速度
  • netlog.js:轉(zhuǎn)儲所有網(wǎng)絡(luò)請求和響應(yīng)
  • netsniff.js:以HAR格式捕獲網(wǎng)絡(luò)流量
  • post.js:將HTTP POST請求發(fā)送到測試服務(wù)器
  • postserver.js:啟動Web服務(wù)器并向其發(fā)送HTTP POST請求
  • server.js:啟動Web服務(wù)器并向其發(fā)送HTTP GET請求
  • serverkeepalive.js:啟動Web服務(wù)器,以純文本格式回答
  • simpleserver.js:啟動Web服務(wù)器,以HTML格式回答

5. Testing

  • run-jasmine.js:運行基于Jasmine的測試
  • run-qunit.js:運行基于QUnit的測試

6. Browser

  • features.js:檢測瀏覽器功能使用modernizr.js
  • useragent.js:更改瀏覽器的用戶代理屬性

今天,我們根據(jù)網(wǎng)頁URL生成圖片,使用的就是rasterize.js:將網(wǎng)頁光柵化為圖像或PDF。

了解rasterize.js

我們來看一下rasterize.js的內(nèi)容(源文件對size的處理有錯誤,這里已修正?。?/p>

"use strict";
var page = require('webpage').create(),
  system = require('system'),
  address, output, size;

if (system.args.length < 3 || system.args.length > 5) {
  console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
  console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
  console.log(' image (png/jpg output) examples: "1920px" entire page, window width 1920px');
  console.log('                  "800px*600px" window, clipped to 800x600');
  phantom.exit(1);
} else {
  address = system.args[1];
  output = system.args[2];
  page.viewportSize = { width: 800, height: 200 };
  if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
    size = system.args[3].split('*');
    page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
                      : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
  } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
    size = system.args[3].split('*');
    if (size.length === 2) {
      var pageWidth = parseInt(size[0].substr(0,size[0].indexOf("px")), 10);
      var pageHeight = parseInt(size[1].substr(0,size[1].indexOf("px")), 10);
      page.viewportSize = { width: pageWidth, height: pageHeight };
      page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
    } else {
      var pageWidth = parseInt(system.args[3].substr(0,system.args[3].indexOf("px")), 10);
      var pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
      page.viewportSize = { width: pageWidth, height: pageHeight };
    }
  }
  if (system.args.length > 4) {
    page.zoomFactor = system.args[4];
  }
  page.open(address, function (status) {
    if (status !== 'success') {
      console.log('Unable to load the address!');
      phantom.exit(1);
    } else {
      window.setTimeout(function () {
        page.render(output);
        phantom.exit();
      }, 200);
    }
  });
}

有過終端開發(fā)的人,對這段命令理解起來都不會太難,這里我就不多說了,后面,我們重點介紹它的使用!

使用方法

首先,我們將Phantom的包引入工程,放在resources目錄下。因為我們要保證本地windows開發(fā)與服務(wù)器linux環(huán)境開發(fā)打包后都能運行,所以,我們將windows和linux兩個包都引入。

然后,我們創(chuàng)建Phantom的使用工具類PhantomTools.class:

package test;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * 網(wǎng)頁轉(zhuǎn)圖片處理類,使用外部CMD
 *
 * @author lekkoli
 */
@Slf4j
public class PhantomTools {

  /**
   * 可執(zhí)行文件phantomjs.exe路徑
   */
  private final String phantomjsPath;
  /**
   * 快照圖生成JS路徑
   */
  private final String rasterizePath;
  /**
   * 臨時圖片前綴
   */
  private static final String FILE_PREFIX = "TIG-AE-";
  /**
   * 臨時圖片后綴
   */
  private static final String FILE_SUFFIX = ".jpg";

  /**
   * 構(gòu)造參數(shù)
   * 獲取phantomjs路徑
   */
  public PhantomTools() {
    String bootPath = new File(this.getClass().getResource("/").getPath()).getPath();
    phantomjsPath = String.join(File.separator, bootPath, "phantomjs-2.1.1-windows", "bin", "phantomjs");
    rasterizePath = String.join(File.separator, bootPath, "phantomjs-2.1.1-windows", "examples", "rasterize.js");
  }

  /**
   * url 中需要轉(zhuǎn)義的字符
   * 1. + URL 中+號表示空格 %2B
   * 2. 空格 URL中的空格可以用+號或者編碼 %20
   * 3. / 分隔目錄和子目錄 %2F
   * 4. ? 分隔實際的 URL 和參數(shù) %3F
   * 5. % 指定特殊字符 %25
   * 6. # 表示書簽 %23
   * 7. & URL 中指定的參數(shù)間的分隔符 %26
   * 8. = URL 中指定參數(shù)的值 %3D
   *
   * @param url 需要轉(zhuǎn)義的URL
   * @return 轉(zhuǎn)義后的URL
   */
  public String parseUrl(String url) {
    String parsedUrl = StringUtils.replace(url, "&", "%26");
    log.info("[解析后的URL:{}]", parsedUrl);
    return parsedUrl;
  }

  /**
   * 根據(jù)URL生成指定fileName的字節(jié)數(shù)組
   *
   * @param url 請求URL
   * @return 圖片字節(jié)數(shù)組
   */
  public byte[] create(String url) {
    return create(url, null);
  }

  /**
   * 根據(jù)URL生成指定fileName的字節(jié)數(shù)組
   *
   * @param url 請求URL
   * @param size 指定圖片尺寸,例如:1000px*800px
   * @return 圖片字節(jié)數(shù)組
   */
  public byte[] create(String url, String size) {
    // 服務(wù)器文件存放地址
    String filePath = FileUtils.getTempDirectoryPath() + FILE_PREFIX + UUID.randomUUID().toString() + FILE_SUFFIX;
    try {
      // 執(zhí)行快照命令
      String command = String.join(StringUtils.SPACE, phantomjsPath, rasterizePath, url, filePath, size);
      log.info("[執(zhí)行命令:{}]", command);
      // 執(zhí)行命令操作
      Process process = Runtime.getRuntime().exec(command);
      // 一直掛起,直到子進程執(zhí)行結(jié)束,返回值0表示正常退出
      if (process.waitFor() != 0) {
        log.error("[執(zhí)行本地Command命令失敗] [Command:{}]", command);
        return new byte[0];
      }
      // 判斷生成的圖片是否存在
      File file = FileUtils.getFile(filePath);
      if (!file.exists()) {
        log.error("[本地文件\"{}\"不存在]", file.getName());
        return new byte[0];
      }
      // 將快照圖片生成字節(jié)數(shù)組
      byte[] bytes = IOUtils.toByteArray(new FileInputStream(file));
      log.info("[圖片生成結(jié)束] [圖片大?。簕}KB]", bytes.length / 1024);
      return bytes;
    } catch (IOException | InterruptedException e) {
      log.error("[圖片生成失敗]", e);
    } finally {
      FileUtils.deleteQuietly(FileUtils.getFile(filePath));
    }
    return new byte[0];
  }
}

上面工具類,通過構(gòu)造方法初始化了命令包路徑,調(diào)用parseUrl()方法對URL中含有的&符號做了替換,最核心的命令執(zhí)行,采用Process對象完成,最后輸出到臨時目錄下的圖片文件。這就是phantomjs對Web訪問頁的圖片生成流程。

其中,Process對象底層調(diào)用的其實就是ProcessBuilder。

public Process exec(String[] cmdarray, String[] envp, File dir)
  throws IOException {
  return new ProcessBuilder(cmdarray)
    .environment(envp)
    .directory(dir)
    .start();
}

ProcessBuilder會調(diào)用ProcessImpl的許多底層native方法完成URL訪問與圖片生成。

測試方法:

public static void main(String[] arg) throws IOException {
  String url = "https://www.cnblogs.com/ason-wxs/";
  PhantomTools phantomTools = new PhantomTools();
  String parsedUrl = phantomTools.parseUrl(url);
  byte[] byteImg = phantomTools.create(parsedUrl);
  File descFile = new File(FileUtils.getTempDirectoryPath() + "test.png");
  FileUtils.touch(descFile);
  FileUtils.writeByteArrayToFile(descFile, byteImg);
}

測試結(jié)果我就不貼出來了,無非將我的博客首頁生成圖片保存到指定文件test.png中。

好了,希望上面對PhantomJS的介紹對你今后工作有所幫助!

以上就是Java利用Phantomjs實現(xiàn)生成圖片的功能的詳細內(nèi)容,更多關(guān)于JAVA 生成圖片的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談java線程中生產(chǎn)者與消費者的問題

    淺談java線程中生產(chǎn)者與消費者的問題

    下面小編就為大家?guī)硪黄獪\談java線程中生產(chǎn)者與消費者的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • Spring Boot結(jié)合IDEA自帶Maven插件如何快速切換profile

    Spring Boot結(jié)合IDEA自帶Maven插件如何快速切換profile

    IDEA是目前 Java 開發(fā)者中使用最多的開發(fā)工具,它有著簡約的設(shè)計風格,強大的集成工具,便利的快捷鍵,這篇文章主要介紹了Spring Boot結(jié)合IDEA自帶Maven插件快速切換profile,需要的朋友可以參考下
    2023-03-03
  • Spring Boot Actuator入門指南

    Spring Boot Actuator入門指南

    SpringBootActuator是SpringBoot提供的一系列產(chǎn)品級特性,用于監(jiān)控應(yīng)用程序、收集元數(shù)據(jù)和運行情況,通過添加依賴,可以通過HTTP或JMX與外界交互,本文介紹Spring Boot Actuator的相關(guān)知識,感興趣的朋友一起看看吧
    2025-02-02
  • java接口用戶上下文的設(shè)計與實現(xiàn)

    java接口用戶上下文的設(shè)計與實現(xiàn)

    這篇文章主要為大家介紹了接口用戶上下文的設(shè)計與實現(xiàn)實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼

    Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼

    本文主要介紹了Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • 十個最常見的Java字符串問題(翻譯)

    十個最常見的Java字符串問題(翻譯)

    這篇文章主要介紹了十個最常見的Java字符串問題(翻譯),需要的朋友可以參考下
    2015-03-03
  • 一文帶你全面了解Java?Hashtable

    一文帶你全面了解Java?Hashtable

    HashTable是jdk?1.0中引入的產(chǎn)物,基本上現(xiàn)在很少使用了,但是會在面試中經(jīng)常被問到。本文就來帶大家一起深入了解一下Hashtable,需要的可以參考一下
    2022-09-09
  • JDK1.6“新“特性Instrumentation之JavaAgent(推薦)

    JDK1.6“新“特性Instrumentation之JavaAgent(推薦)

    這篇文章主要介紹了JDK1.6“新“特性Instrumentation之JavaAgent,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • java編程實現(xiàn)多人聊天室功能

    java編程實現(xiàn)多人聊天室功能

    這篇文章主要為大家詳細介紹了java編程實現(xiàn)多人聊天室功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 在IDEA中 實現(xiàn)給main方法附帶參數(shù)的操作

    在IDEA中 實現(xiàn)給main方法附帶參數(shù)的操作

    這篇文章主要介紹了在IDEA中 實現(xiàn)給main方法附帶參數(shù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01

最新評論

仙桃市| 休宁县| 聂拉木县| 醴陵市| 鹤庆县| 集贤县| 克拉玛依市| 丹寨县| 偏关县| 沁阳市| 高阳县| 攀枝花市| 郴州市| 天门市| 苗栗市| 东乌珠穆沁旗| 镇安县| 广平县| 改则县| 抚州市| 开封市| 杭锦旗| 台东市| 芜湖市| 阳原县| 稷山县| 清徐县| 余姚市| 泰兴市| 威海市| 黄石市| 五指山市| 若尔盖县| 金阳县| 巴彦淖尔市| 皋兰县| 海口市| 侯马市| 五华县| 理塘县| 合水县|