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