最近的项目中,需要实现一个将网页中显示的内容导出为图片的功能,故研究了一下可以实现这个功能的各种方式,整理在此,以供以后使用。

p.s. 本人为java研发,所有涉及的代码,实现方式均为java的方式。

前台方式

1. 利用html2canvas实现前台截屏

html2canvas项目的gitHub地址
html2canvas示例

html2canvas可以将HTML代码块进行截取,并生成快照形式的canvas,然后可以利用html5的下载功能提供图片的下载接口,供用户下载。

优点:前台技术,实现比较容易。

缺点:此项目使用了html5的技术,因此在对IE的兼容上,只可以在IE9+的版本上使用。

使用时,需要引用jQuery.js和html2canvas.js。(html2canvas.js可以在github上下载)

具体JavaScript代码如下:

var canvas = function () {html2canvas($("#chart"), {onrendered: function (canvas) {$("#class11").html(canvas);//将id为“class11”部分的代码转换为canvasvar type = 'png';//图片类型为pngvar imgData = canvas.toDataURL('png');//将图片转换为png类型的流var _fixType = function (type) {type = type.toLowerCase().replace(/jpg/i, 'jpeg');var r = type.match(/png|jpeg|bmp|gif/)[0];return 'image/' + r;};var saveFile = function (data, filename) {var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');save_link.href = data;save_link.download = filename;var event = document.createEvent('MouseEvents');event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);save_link.dispatchEvent(event);};//下载时的文件名var filename = 'baidufe_' + (new Date()).getTime() + '.' + type;// 下载文件saveFile(imgData, filename);}});
};

后台方式(java)

1. 利用html2image实现

html2image的地址(google)
html2image是可以识别html标签并将html转换成图片的java项目。

优点:后台转换,故对浏览器的版本基本没有要求。

缺点:对样式的识别不是很好,转换出来的图片比较简单,基本没有可以兼容的样式。

使用方式:maven中引用如下依赖:

<dependency><groupId>com.github.xuwei-k</groupId><artifactId>html2image</artifactId><version>0.1.0</version>
</dependency>

2. 利用DJNativeSwing项目实现

纯java代码实现。使用DJNativeSwing这个项目,构建一个swing浏览器,打开网址,之后截取图片。(需要eclipse的swt库支持)

优点:纯java实现。

缺点:需要多线程的支持,只在控制台方式实现过(由于本人对于多线程的掌握较弱,目前没有在spring项目中实现这个方法,求大神指导~~)

使用这个方法,需要引用的maven依赖如下:

<dependency><groupId>com.hynnet</groupId><artifactId>DJNativeSwing</artifactId><version>1.0.0</version>
</dependency><dependency><groupId>com.hynnet</groupId><artifactId>DJNativeSwing-SWT</artifactId><version>1.0.0</version>
</dependency><dependency>                            <groupId>org.eclipse.swt.org.eclipse.swt.win32.win32.x86_64.4.3.swt</groupId><artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId><version>4.3</version>
</dependency>

实现代码如下(引用自http://blog.csdn.net/buddyuu/article/details/52699997):

public class PrintScreen4DJNativeSwingUtils extends JPanel {private static final long serialVersionUID = 1L;// 行分隔符final static public String LS = System.getProperty("line.separator", "/n");// 文件分割符final static public String FS = System.getProperty("file.separator", "//");// 当网页超出目标大小时 截取final static public int maxWidth = 2000;final static public int maxHeight = 1400;/*** @param file*            预生成的图片全路径* @param url*            网页地址* @param width*            打开网页宽度 ,0 = 全屏* @param height*            打开网页高度 ,0 = 全屏* @return boolean*/public PrintScreen4DJNativeSwingUtils(final String file, final String url, final String WithResult) {super(new BorderLayout());JPanel webBrowserPanel = new JPanel(new BorderLayout());final JWebBrowser webBrowser = new JWebBrowser(null);webBrowser.setBarsVisible(false);webBrowser.navigate(url);webBrowserPanel.add(webBrowser, BorderLayout.CENTER);add(webBrowserPanel, BorderLayout.CENTER);JPanel panel = new JPanel(new FlowLayout());webBrowser.addWebBrowserListener(new WebBrowserAdapter() {// 监听加载进度public void loadingProgressChanged(WebBrowserEvent e) {// 当加载完毕时if (e.getWebBrowser().getLoadingProgress() == 100) {String result = (String) webBrowser.executeJavascriptWithResult(WithResult);int index = result == null ? -1 : result.indexOf(":");NativeComponent nativeComponent = webBrowser.getNativeComponent();Dimension originalSize = nativeComponent.getSize();Dimension imageSize = new Dimension(Integer.parseInt(result.substring(0, index)),Integer.parseInt(result.substring(index + 1)));imageSize.width = Math.max(originalSize.width, imageSize.width + 50);imageSize.height = Math.max(originalSize.height, imageSize.height + 50);nativeComponent.setSize(imageSize);BufferedImage image = new BufferedImage(imageSize.width, imageSize.height,BufferedImage.TYPE_INT_RGB);nativeComponent.paintComponent(image);nativeComponent.setSize(originalSize);// 当网页超出目标大小时if (imageSize.width > maxWidth || imageSize.height > maxHeight) {// 截图部分图形image = image.getSubimage(0, 0, maxWidth, maxHeight);// 此部分为使用缩略图/** int width = image.getWidth(), height = image* .getHeight(); AffineTransform tx = new* AffineTransform(); tx.scale((double) maxWidth /* width, (double) maxHeight / height);* AffineTransformOp op = new AffineTransformOp(tx,* AffineTransformOp.TYPE_NEAREST_NEIGHBOR); //缩小 image* = op.filter(image, null);*/}try {// 输出图像ImageIO.write(image, "jpg", new File(file));} catch (IOException ex) {ex.printStackTrace();}// 退出操作System.exit(0);}}});add(panel, BorderLayout.SOUTH);}// 以javascript脚本获得网页全屏后大小public static String getScreenWidthHeight() {StringBuffer jsDimension = new StringBuffer();jsDimension.append("var width = 0;").append(LS);jsDimension.append("var height = 0;").append(LS);jsDimension.append("if(document.documentElement) {").append(LS);jsDimension.append("  width = Math.max(width, document.documentElement.scrollWidth);").append(LS);jsDimension.append("  height = Math.max(height, document.documentElement.scrollHeight);").append(LS);jsDimension.append("}").append(LS);jsDimension.append("if(self.innerWidth) {").append(LS);jsDimension.append("  width = Math.max(width, self.innerWidth);").append(LS);jsDimension.append("  height = Math.max(height, self.innerHeight);").append(LS);jsDimension.append("}").append(LS);jsDimension.append("if(document.body.scrollWidth) {").append(LS);jsDimension.append("  width = Math.max(width, document.body.scrollWidth);").append(LS);jsDimension.append("  height = Math.max(height, document.body.scrollHeight);").append(LS);jsDimension.append("}").append(LS);jsDimension.append("return width + ':' + height;");return jsDimension.toString();}public static boolean printUrlScreen2jpg(final String file, final String url, final int width, final int height) {NativeInterface.open();SwingUtilities.invokeLater(new Runnable() {public void run() {String withResult = "var width = " + width + ";var height = " + height + ";return width +':' + height;";if (width == 0 || height == 0)withResult = getScreenWidthHeight();JFrame frame = new JFrame("网页截图");// 加载指定页面,最大保存为640x480的截图frame.getContentPane().add(new PrintScreen4DJNativeSwingUtils(file, url, withResult),BorderLayout.CENTER);frame.setSize(640, 480);// 仅初始化,但不显示frame.invalidate();frame.pack();frame.setVisible(false);}});NativeInterface.runEventPump();return true;}public static void main(String[] args) {  PrintScreen4DJNativeSwingUtils.printUrlScreen2jpg("1122.jpg", "https://www.baidu.com", 1400, 900);}
}

3. 利用phantomJs实现

phantomJs的GitHub地址
phantomJs官网

phantom利用的是webKit内核,全面支持web而不需浏览器支持,快速,原生支持各种Web标准。

优点:速度快,使用简单。

缺点:需要在项目的服务器端引用exe文件进行截图,并发性能有待考证。

使用这个方式,需要去官网下载最新的phantomJs脚本。官网地址在上面的链接中。

具体代码如下(引用自http://www.cnblogs.com/lekko/p/4796062.html):

/*** 网页转图片处理类,使用外部CMD*/
public class PhantomTools {private static final Logger _logger = Logger.getLogger(PhantomTools.class);private static final String _tempPath = "D:/data/temp/phantom_";private String basePath;private static final String _shellCommand1 = "phantomjs ";private static final String _shellCommand2 = "rasterize.js ";private String _file;private String _size;/*** 构造截图类* @param hash 用于临时文件的目录唯一化* @param basePath phantomJs所在路径*/public PhantomTools(int hash, String basePath) {_file = _tempPath + hash + ".png";this.basePath = basePath;}/*** 构造截图类* @param hash 用于临时文件的目录唯一化* @param size 图片的大小,如800px*600px(此时高度会裁切),或800px(此时 高度最少=宽度*9/16,高度不裁切)* @param basePath phantomJs所在路径*/public PhantomTools(int hash, String size, String basePath) {_file = _tempPath + hash + ".png";if (size != null)_size = " " + size;this.basePath = basePath;}/*** 将目标网页转为图片字节流* @param url 目标网页地址* @return 字节流*/public byte[] getByteImg(String url) throws IOException {BufferedInputStream in = null;ByteArrayOutputStream out = null;File file = null;byte[] ret = null;try {if (exeCmd(basePath + _shellCommand1 + basePath + _shellCommand2 + url + " " + _file + (_size != null ? _size : ""))) {file = new File(_file);if (file.exists()) {out = new ByteArrayOutputStream();byte[] b = new byte[5120];in = new BufferedInputStream(new FileInputStream(file));int n;while ((n = in.read(b, 0, 5120)) != -1) {out.write(b, 0, n);}file.delete();ret = out.toByteArray();}} else {ret = new byte[] {};}} finally {try {if (out != null) {out.close();}} catch (IOException e) {_logger.error(e);}try {if (in != null) {in.close();}} catch (IOException e) {_logger.error(e);}if (file != null && file.exists()) {file.delete();}}return ret;}/*** 执行CMD命令*/private static boolean exeCmd(String commandStr) {BufferedReader br = null;try {Process p = Runtime.getRuntime().exec(commandStr);if (p.waitFor() != 0 && p.exitValue() == 1) {return false;}} catch (Exception e) {_logger.error(e);} finally {if (br != null) {try {br.close();} catch (Exception e) {_logger.error(e);}}}return true;}
}

Java实现网页截屏功能(图片下载功能)的几种方式(整理)相关推荐

  1. Java实现网页截屏功能(基于phantomJs)

    公司最近有个需求:把用户第一次的测量身体信息和最近一次测量信息进行对比,并且需要把对比的数据截成图片可以发给用户(需要在不打开网页的情况下实时对网页进行截图然后保存到服务器上,返回图片地址),通过网上 ...

  2. java 文件下载详解_Java 从网上下载文件的几种方式实例代码详解

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package com.github.pandafang.tool; import java.io.BufferedOutputStream; i ...

  3. java 截图_Java实现网页截屏

    下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. import java.awt.AWTException; import java.awt ...

  4. java网页截图_Java实现的简单网页截屏功能示例

    本文实例讲述了Java实现的简单网页截屏功能.分享给大家供大家参考,具体如下: package awtDemo; import java.awt.AWTException; import java.a ...

  5. java在线截图_JAVA之网页截屏

    先吐槽一下下: 表示接近两个月没有敲代码了,现在看一下代码都感觉有点生了.三天打鱼两天晒网是不行的,再说我本来就有"健忘症",真的是木有办法啊 ̄へ ̄.我一直信奉一句话:" ...

  6. JavaScript实现网页截屏方法总结

    " 关注『前端开发博客』公众号,回复 加群 " 最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,以及在后台运行的nodeJs的方法.主要看了以下几个: ...

  7. JavaScript 实现网页截屏五种方法

    JavaScript 实现网页截屏五种方法 最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,以及在后台运行的nodeJs的方法.主要看了以下几个: PhantomJS P ...

  8. JS 实现网页截屏五种方法

    最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,以及在后台运行的nodeJs的方法.主要看了以下几个: PhantomJS Puppeteer(chrome headle ...

  9. 【JS】1007- JavaScript实现网页截屏的5种方法

    作者:luckness 原文:https://segmentfault.com/a/1190000037673677 最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,以及 ...

最新文章

  1. FLEX中Sequence实例教程. 顺序执行的效果.
  2. JAVA学习笔记——常量与变量
  3. [Android1.5]DigitalClock自定义日期输出格式
  4. C++和Python,JSON文件的读取和保存
  5. 从零开始学习Hadoop--第2章 第一个MapReduce程序
  6. 生成jni的android.mk,Android Studio 3.5版本JNI生成SO文件详解
  7. Python批量导入图片生成能治疗颈椎病的HTML5版课件
  8. 卡诺模型案例分析_质量管理神器,Kano模型您可知道?
  9. python程序员面试题精选100题_在Python程序员面试中被问的最多的10道题
  10. 三轴合并_用两套乐高60107合并成铰接式云梯消防车,看看和60112有什么区别
  11. Js批量下载花瓣网及堆糖网专辑图片
  12. 和利时 浙大中控DCS组态软件,操作员在线模拟软件
  13. mysql 同比sql_mysql计算同比和环比的区别_【面试真题】Mysql实现计算同比、环比...
  14. 阿西莫夫定律:自动驾驶汽车算不算机器人?该不该伤人?
  15. matlab特征方程的根,MATLAB 求解特征方程的根轨迹图稳定性分析
  16. 用c语言实现三子棋,它来了!!
  17. 计算机管理没有固态硬盘,电脑的BIOS中没有固态硬盘启动选项怎么办?
  18. 抓取检测之 End-to-end Trainable Deep Neural Network for Robotic Grasp Detection and Semantic Segmentation
  19. 人生之路1.20代码 第四部分
  20. 10亿手机号如何去重?(BitMap)

热门文章

  1. 《利用python进行数据分析》勘误
  2. 汽车网站模板如何最大化的满足建站要求?
  3. 最好用的服务器连接管理工具
  4. Glider CodeForces - 1041D
  5. H5,SIP,Web,硬件视频会议,多方视频互动的架构和选型
  6. 提高sql查询性能-使用instr函数替换like
  7. Linux下的OpenGL——Mesa和GLX简介
  8. 一般实验室、专用实验室及研究工作室的设计
  9. 1、My Scripts
  10. MATLAB图像处理之图像的均值滤波和中值滤波(附代码)