1、Java截取网页形成图片

1、闲扯

有一个GUI编程的开源框架叫SWT(Standard Widget Toolkit),它与sun公司的AWT、Swing类似。非界面编程人员,这里就不扯它们的优缺点了。

或许很多人都没听说过SWT,但是如果说出由它制作出来的一个工具,大家可能会对它肃然起敬。这个工具就是IBM开发的Eclipse。于是我们如果要给Eclipse开发插件,那么就得对SWT非常了解了。

2、要求

要截取网页形成图片,需要1-2要求。这里的1是要配置java.libarary.path;2是需要两个jar包。

1要求:配置java.library.path。

也许大家都知道配置环境变量path。然而这个环境变量和这个java.library.path有什么作用呢?

path:指定的是classpath,也就是通过这个变量可以找到相应的Java类;而有时候,Java可能需要利用到本地的代码库文件(在Windows上为dll文件,在Linux上为so文件)。系统如何找到这个动态链接库呢?当然也需要一个变量指向,这个变量就是java.library.path。

2需求:拿到两个jar包。

一个jar包是Eclipse当中的。打开Eclipse的安装目录,我的目录为“E:\eclipse\plugins”,在这个下面会有一个org.eclipse.swt.win32.x86_64_***.jar的包。

另一个包就是基于这个Eclipse的包开发的进行实际应用(如:截取网页形成图片、渲染成Html文件)的jar包。这个jar包具体是谁开发的就不知道了。它的项目点击可下载。

3、部署

将两个包加到自己的项目当中。另外,在另外一个地方将Eclipse里面拿出的那个jar进行解压,可以看到里面有三个dll的动态链接库文件。我们将这三个文件拷贝到某个目录下。我的目录为“D:/swt”。 然后,在开发运行的时候可以配置一下虚拟机的参数,方法为:右键点击项目——>Run as——>Run Configurations。如下进行配置,这样就使得java.library.path指向了程序运行过程中所需要的几个动态链接库。要不然会抛出:java.lang.UnsatisfiedLinkError no *****.dll in java.library.path,如此的异常。到这里,我们就可以进行测试了。看看它惊奇的效果。

4、分析

我们在学习GUI编程的时候,都知道,先要进行视图的布局。这里的视图就是一个个的面板。设置面板的样式、大小。面板上面叠加面板做出超炫的样式,或者在面板上添加监听事件与用户进行交互。

这里进行截取网页也是如此。网页怎么被渲染出来的?网页的样式布局是被浏览器根据脚本渲染出来的效果,这里我们就利用了浏览器这个“面板”。在浏览器的下面还有一个面板“shell”。这也是说,shell面板上有一个browser的面板,我们传一个URL给browser面板后,面板能对其返回的页面进行渲染。这里我们执行browser面板的大小就为一帧,现在我们只关心它的高度,这个高度是可以由我们指定的(当然需要修改其源代码),默认为500。我们通过在java代码当中执行javascript脚本,就能返回这时候网页内容的总高度。这个总高度/500+1就是我们需要将这个网页刷屏几次才能得到一个完整的网页。项目的核心方法如下(默认的要刷好几次屏才能将网页捕获完整;我将其改成刷一次屏就能捕获完整的网页,但是要将其线程睡眠时间弄长点,要不然网页还没渲染出来,就已经捕获完了,那么形成的图片的数据就会有所残缺):

 1 final int perHight=2027;
 2     public void render(final File saveLocation) throws RenderingException
 3     {
 4         final File localSaveLocation = new File(saveLocation.getParentFile().getAbsolutePath() + File.separator + "localhost");
 5         localSaveLocation.mkdirs();
 6         System.out.println("Saving temporary images in directory :" + localSaveLocation.getAbsolutePath());
 7
 8         String widthStr = null;
 9         //根据javascript脚本得到网页内容的宽度和高度
10         widthStr = this.getJavascriptValue("document.body.scrollWidth+‘-‘+document.body.scrollHeight");
11         if (widthStr == null)
12             throw new RenderingException("Could not acquire Document height andf width by javascript.");
13
14         final int width = SCREEN_WIDTH;
15         //如果网页内容高度大于10000那么就取值10000,否则就是内容高度本身
16         int nonFinalHeight = Math.min(10000, Integer.parseInt(widthStr.split("-")[1]));
17
18         //perHight就是每一帧刷多高,如果网页内容高度小于一帧的取值高度就取值一帧的高度;否则,就取值内容的高度
19         final int height = nonFinalHeight < perHight ? perHight: nonFinalHeight;
20
21         System.out.println("Screen sizes :" + width + " ," + height);
22
23         int start=0;
24
25         //然后将作为内容高度的height变量除以一帧高度,也就是要对这个网页进行刷屏多少次。
26         //我们也就要将网页内容进行移动,移动网页内容,只要移动浏览器Y轴上的滚动条就行,
27         //初始状态,不需要滚动,也就是当i=0时。当i=1时,就需要滚动一帧的内容,因为每次滚动,滚动条初始在0位置,因此每次start都是从0开始。
28
29
30         for (int i = 0; i < 1 + (height / perHight); i++)
31         {
32             if (i != 0)
33             {
34                 this.execute("window.scrollTo("+start+"," + i * (perHight - scrollbarY) + ");");
35                 try
36                 {
37                     Thread.sleep(10000);//这个时间稍微长点,要不页面还没有刷出来就已经捕获了这一帧
38                 }
39                 catch (InterruptedException e)
40                 {
41                     throw new RenderingException(e);
42                 }
43             }
44             final int j = i;
45             //下面的异步方法就是捕获一帧的网页
46             //这里呈现的屏幕的高度和宽度是固定的,只是在这个固定的区域当中,内容在变而已。
47             //因此,我们只要对这一块固定的区域进行捕获就可以了。
48             display.syncExec(new Runnable()
49             {
50                 public void run()
51                 {
52                     if (j == 0 || j < (height / perHight))
53                         capture(localSaveLocation.getAbsolutePath(), j, SCREEN_WIDTH,perHight, 0, 0);
54                     else
55                         capture(localSaveLocation.getAbsolutePath(), j, SCREEN_WIDTH, (height % perHight == 0 ? perHight : height % perHight), 0, perHight - (height % perHight));
56                 }
57             });
58         }
59         display.syncExec(new Runnable()
60         {
61             public void run()
62             {
63                 try
64                 {
65                     final Image result = new Image(display, width, height);
66                     GC gc = new GC(result);
67                     for (int i = 0; i < (1 + height / perHight); i++)
68                     {
69
70                         ImageLoader imageLoader = new ImageLoader();
71                         File partialImageFile = new File(localSaveLocation, "savedImage" + i + ".jpg");
72                         FileInputStream fis = new FileInputStream(partialImageFile);
73                         Image loadedImage = new Image(display, imageLoader.load(fis)[0]);
74                         gc.drawImage(loadedImage, 0, i * (perHight - scrollbarY));
75                         loadedImage.dispose();
76                         fis.close();
77                         // Delete the partial image file once we are done with
78                         // it :
79                         partialImageFile.delete();
80                     }
81                     gc.dispose();
82                     ImageLoader imageSaver = new ImageLoader();
83                     imageSaver.data = new ImageData[] { result.getImageData() };
84                     System.out.println("Saving image to location :" + saveLocation);
85                     FileOutputStream fos = new FileOutputStream(saveLocation);
86                     imageSaver.save(fos, SWT.IMAGE_JPEG);
87                     fos.close();
88                     result.dispose();
89
90                 }
91                 catch (Exception e)
92                 {
93                     e.printStackTrace();
94                 }
95             }
96         });
97
98     }
时间: 2024-10-03 14:55:45

1、Java截取网页形成图片的相关文章

CentOS7下python3 selenium3 使用Chrome的无头浏览器 截取网页全屏图片

前言 selenium是一个模拟浏览器的自动化执行框架,但是如果每次执行都要打开浏览器来处理任务的话,效率上都不高.最重要的是如果安装在Centos7服务器环境下,打开浏览器来模拟操作是更加不合适的,尤其是碰上需要截取网页图片这样的需求. 这时候就要考虑使用Chrome的无头浏览器模式了.所谓的无头浏览器模式也就是不需要打开浏览器,但是却可以起到模拟打开浏览器的执行效果,一切无界面执行. 下面来看看如果安装部署到执行. 1.安装chrome 1.1 添加google的repo源 vim /etc

将网页另存为图片的Java框架

首先要了解的是java在图像这一块非常弱.用java实现截图倒不难,原理吗就是把当前屏幕存成一个图,然后获取鼠标拉去的想去位置然后把截取的图保存到panel里边,再生成图片即可.那么这里要说什么呢?好吧下面就说几个将网页保存为图片的框架: 1.html2image 网上炒这个还不少呢.我说这个就是原声的java代码进行封装的一个jar包.效果非常差,代码就不贴了网上好多. 2.cobra 如果你不知道这个的话,你应该听说过lobobrowser,纯java实现的浏览器,测试了下,除了启动慢的要死

Java Web:使用Servlet生成网页随机图片验证码

最近在学习Java Web开发,做了一个生成网页随机图片验证码的例子,在此记录. 一.新建Servlet项目: 在MyEclipse中新建Servlet项目,一步步操作就OK,在此不再赘述.建好之后文件目录树如下图: 二.源代码实现: (1)java代码: package com.zdt.identity; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.

如何以Java实现网页截图技术

今天看到某网友关于"如何以Java实现网页截图技术"的咨询帖,由于出现该咨询的地点非常不适合较长回复,故以博文形式回答. 事实上,如果您想以Java实现网页截图,也就是"输入一段网址,几秒钟过后就能截取一张网页缩略图"的效果.那么,您至少有3种方式可以选择. 1.最直接的方式--使用Robot 方法详解:该方法利用Robat提供的强大桌面操作能力,硬性调用浏览器打开指定网页,并将网页信息保存到本地. 优势:简单易用,不需要任何第三方插件. 缺点:不能同时处理大量数据

使用java技术,批量进行图片水印处理

步骤: 1.建立web工程[完成] 2.编写网页(含有图片) 3.编写过滤器,实现对所有请求页面的图片加水印 核心代码: /** * 所有请求均要经过此过滤方法 */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletReque

Android使用WebView显示网页(图片缩放)

上周写了一篇关于webview的博文:Android使用WebView显示网页(图片大小的处理及内容的自适应) 后来通过自己想的第三种办法实现了图片的适配,方法是设置html的img标签属性,把图片的宽度设置为设备屏幕的宽度,涉及的知识点就是,获取设备宽度值.java代码 添加/修改 html标签属性. 1. 获取设备屏幕信息: /** * 获取设备的屏幕信息 * @param activity * @return */ public static DeviceInfo getDevicesPi

如何利用Win10Edge浏览器来截取网页长图?

有时我们在工作演示时会需要截取网页上的图片,不过简单的截图可以,但如果需要截取超过屏幕大小的整个网页,你是不是就有些束手无策了.虽然拼接图片也是种方法,但毕竟还是不方便,下面好系统重装助手就教你在Win10系统中如何截取网页长图. Win10系统截取网页长图的方法 工欲善其事必先利其器,有了工具,我们就可以顺利完成网页长图的截取.这个工具就是Win10系统自带的Edge浏览器.1.打开Edge浏览器,在右上方找到并点击"添加笔记"功能键.2.在笔记功能区内,找到并点击"剪辑&

Java截取视频首帧并旋转正向

package test; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.

爬虫-使用模拟浏览器操作(截取网页)

最近遇到一个问题就是,如何模拟真实浏览器行为然后截取显示的网页. 方案 模拟登陆网站或者直接使用cookie登陆. 对指定页面按钮进行点击刷新页面,截取网页. 我们使用selenium库来操作浏览器驱动,即执行浏览器相应的驱动命令,实现相应的浏览器操作. 准备工作 selenium库 浏览器自动化测试框架,其作用是通过操作浏览器驱动来控制浏览器行为,达到模拟真实用户操作浏览器的效果.原理为自动化测试python脚本-->浏览器driver -->浏览器.官网 python中文文档 python