English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java PhantomJs Completes HTML Image Output Function

Using phantomJs to implement the output of html web pages as images

I. Background

How to generate a picture in a mini-program and share it to the Moments? Currently, there seems to be no good solution for the front-end, so it can only be supported by the backend in a sneaky way. Then, how can we play around with it?

Generating images is relatively simple

For simple scenarios, it can be supported directly with jdk, and generally there is not too complex logic

I've written a logic for image synthesis before, using awt: Image Synthesis

Universal and complex templates

Simple ones can be supported directly, but for more complex ones, it's definitely not pleasant to have the backend support them. I've also searched for some open-source libraries that render html on github, but I'm not sure if it's because of the wrong approach or something else, as I didn't find any satisfactory results

Now, how to support complex templates?

That is, this guide, using phantomjs to render html, supporting the generation of pdf, images, and parsing of dom all work well, and the next step is to demonstrate how to combine phantomjs to build a service that renders web pages into images

II. Preliminary preparation

1. Phantom.js installation

# 1. Download
## Mac system
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-macosx.zip
## Linux system
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
## Windows system
## Don't play anymore, it's not interesting
# 2. Unzip
sudo su 
tar -jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
# If there is an error when unzipping, install the following
# yum -y install bzip2
# 3. Installation
## Simply, move to the bin directory
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
# 4. Verify if ok
phantomjs --version
# Output the version number, indicating ok

2java dependency configuration

maven configuration to add dependencies

!--phantomjs -->
<dependency>
  <groupId>org.seleniumhq.selenium/groupId>
  <artifactId>selenium-java/artifactId>
  <version>2.53.1</version>
</dependency>
<dependency>
  <groupId>com.github.detro</groupId>
  <artifactId>ghostdriver</artifactId>
  <version>2.1.0</version>
</dependency>
<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

Let's go

The main logic for rendering html images by calling phantomjs is as follows

public class Html2ImageByJsWrapper {
  private static PhantomJSDriver webDriver = getPhantomJs();
  private static PhantomJSDriver getPhantomJs() {
    //Set necessary parameters
    DesiredCapabilities dcaps = new DesiredCapabilities();
    //ssl certificate support
    dcaps.setCapability("acceptSslCerts", true);
    //Screenshot support
    dcaps.setCapability("takesScreenshot", true);
    //CSS search support
    dcaps.setCapability("cssSelectorsEnabled", true);
    //JavaScript support
    dcaps.setJavascriptEnabled(true);
    //Driver support (the second parameter indicates the path where your phantomjs engine is located, which/whereis phantomjs can view it)
    // fixme Here is the execution, it can be considered to judge whether the system has installed it and to obtain the corresponding path or to open it to specify the path
    dcaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "/usr/local/bin/phantomjs"
    //Create a headless browser object
    return new PhantomJSDriver(dcaps);
  }
  public static BufferedImage renderHtml2Image(String url) throws IOException {
    webDriver.get(url);
    File file = webDriver.getScreenshotAs(OutputType.FILE);
    return ImageIO.read(file);
  }
}

Test case

public class Base64Util {
  public static String encode(BufferedImage bufferedImage, String imgType) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ImageIO.write(bufferedImage, imgType, outputStream);
    return encode(outputStream);
  }
  public static String encode(ByteArrayOutputStream outputStream) {
    return Base64.getEncoder().encodeToString(outputStream.toByteArray());
  }
}
@Test
public void testRender() throws IOException {
  BufferedImage img = null;
  for (int i = 0; i < 20; ++i) {
    String url = "https://my.oschina.net/u/566591/blog/1580020";
    long start = System.currentTimeMillis();
    img = Html2ImageByJsWrapper.renderHtml2Image(url);
    long end = System.currentTimeMillis();
    System.out.println("cost: " + (end - start));
  }
  System.out.println(Base64Util.encode(img, "png");
}

The generated images are not attached, those who are interested can directly go to my website for practical testing

III. Network Test

A simple web application has been deployed on the Aliyun server, supporting the function of html output image; because it is a beggar version, and the front-end template used is quite cool, so it opens slowly.

Operation demonstration:

V. Project

Project address:

quick-media

QuickMedia is an open-source project focusing on multimedia services such as image, audio, video, and QR code processing.

The above code has been tested by us. If you still have any questions or need to discuss, please leave a message below. Thank you for your support of the Yell Tutorial.

You May Also Like