1、如何以 Java 实现网页截图技术 - 【Java 究竟怎么玩?】 - CSDN 博客您查询的关键词是:java 网页截图 。如果打开速度慢,可以尝试快速版;如果想保存快照,可以添加到搜藏;如果想更新或删除快照,可以投诉快照。(百度和网页 http:/ 的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。)【Java 究竟怎么玩?】思考因为存在,存在所以思考目录视图 摘要视图 订阅 公告:CSDN 博客积分系统正式上线!如何以 Java 实现网页截图技术 分类: JAVA 应用 技术文章 2010-03-06 23:40 5452 人阅读 评论(63) 收藏
2、举报 今天看到某网友关于“如何以 Java 实现网页截图技术”的咨询帖,由于出现该咨询的地点非常不适合较长回复,故以博文形式回答。事实上,如果您想以 Java 实现网页截图,也就是“输入一段网址,几秒钟过后就能截取一张网页缩略图”的效果。那么,您至少有 3 种方式可以选择。1、最直接的方式使用 Robot 方法详解:该方法利用 Robat 提供的强大桌面操作能力,硬性调用浏览器打开指定网页,并将网页信息保存到本地。 优势:简单易用,不需要任何第三方插件。缺点:不能同时处理大量数据,技术含量过低,属于应急型技巧。实现方法:使用如下代码即可。public static void main(Stri
3、ng args) throws MalformedURLException,IOException, URISyntaxException, AWTException /此方法仅适用于 JdK1.6 及以上版本Desktop.getDesktop().browse(new URL(“http:/ robot = new Robot();robot.delay(10000);Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize();int width = (int) d.getWidth();int heigh
4、t = (int) d.getHeight();/最大化浏览器robot.keyRelease(KeyEvent.VK_F11);robot.delay(2000);Image image = robot.createScreenCapture(new Rectangle(0, 0, width,height);BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics g = bi.createGraphics();g.drawImage(image, 0, 0, width,
5、 height, null);/保存图片ImageIO.write(bi, “jpg“, new File(“google.jpg“);2、最常规的方式利用 JNI,调用第三方 C/C+组件 方法详解:目前来讲,Java 领域对于网页截图组件的开发明显不足(商机?) ,当您需要完成此种操作时,算得上碰到了 Java 的软肋。但是,众所周知 Java 也拥有强大的 JNI 能力,可以轻易将 C/C+开发的同类组件引为己用。 优势:实现简单,只需要封装对应的 DLL 文件,就可以让 Java 实现同类功能。劣势:同其他 JNI 实现一样,在跨平台时存在隐患,而且您的程序将不再属于纯 Java 应用
6、。实现方法:可参见此用例,具体封装何种 C/C+组件请自行选择。PS:示例来源于 ACA HTML to Image Converter 项目(http:/ ) ,这是一个收费的 HTML 转 Image 第三方组件,但封装方式在 Java 中大同小异。引用 JNI 封装:import sun.awt.*;import java.awt.*;import javax.swing.*;import java.awt.event.*;import java.awt.*;import java.awt.peer.*;public class SnapstaticSystem.loadLibrary(
7、“Snap“);public static void main( String argv )Snap t_xSnap = new Snap();t_xSnap.Start(“http:/“, “snapshot-google.png“);public native void Start(String pi_strURL, String pi_strImageName);CPP 部分的实现:#include #include #include “snap.h“#pragma comment(lib,“atl.lib“)#import “./acawebthumb.dll“ no_namespac
8、eJNIEXPORT void JNICALL Java_Snap_Start(JNIEnv *pEnv, jobject, jstring pi_strUrl, jstring pi_strFileName)CoInitialize(0);_bstr_t t_strUrl = pEnv-GetStringUTFChars(pi_strUrl, 0);_bstr_t t_strFileName = pEnv-GetStringUTFChars(pi_strFileName, 0);IThumbMakerPtr HTML_Converter = NULL;HRESULT hr = HTML_Co
9、nverter.CreateInstance(L“ACAWebThumb.ThumbMaker“);if (SUCCEEDED(hr) HTML_Converter-SetURL(t_strUrl);if ( 0 = HTML_Converter-StartSnap() )HTML_Converter-SaveImage(t_strFileName);if (HTML_Converter)HTML_Converter.Release();CoUninitialize(); 以该组件图像化 yahoo 界面的效果图:3、最扎实的方法自行解析 HTML 标记,并将其图像化 方法详解:众所周知,HT
10、ML 之所以在浏览器中以具体的网页格式出现,并非服务器端传了一整个应用到客户端,而是源自于浏览器对于客户端自行解析的结果。因此,只要我们将对应的解析一一实现,那么将网页图形化,就将不是什么难事。 优势:纯 Java 实现,一劳永逸,一旦开发完成则永远通用,而且有一定的商用价值。劣势:开发费时,且需要针对不同语法做精确分析,才能保证输出的基本正确。尤其在涉及到 JavaScript 解析时,难度将尤其增大。实现方法:目前尚无具体案例可供参考。但是,由于 Java 有 jdic 之类的浏览器项目存在(https:/ ) ,而 Java 图形界面又属绘制生成。从理论上说,我们可以将所有具备 Grap
11、hics 的组件图形化保存。而如果自行解析,那么您需要建立 HTML 解析器(或使用第三方的,万幸 Java 在这方面的组件很多) ,了解 Java2D 机制,了解何时该使用 drawString 绘制文字,何时又该使用drawImage 插入图片等等。补充: 这是一个利用内置浏览器截图的示例,使用了 DJNativeSwing 组件。示例工程下载地址(Eclipse 工程,含 lib):http:/ java.awt.BorderLayout;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.image.
12、BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.SwingUtilities;import chrriis.dj.nativeswing.swtimpl.NativeComponent;import chrriis.dj.nativeswing.swtimpl.NativeInterface;import ponents.J
13、WebBrowser;import ponents.WebBrowserAdapter;import ponents.WebBrowserEvent;public class Main 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(
14、“file.separator“, “/“);/以 javascript 脚本获得网页全屏后大小final static StringBuffer jsDimension;static 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.ap
15、pend(“ 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 = M
16、ath.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);“).app
17、end(LS);jsDimension.append(“ height = Math.max(height, document.body.scrollHeight);“).append(LS);jsDimension.append(“).append(LS);jsDimension.append(“return width + : + height;“);/DJNativeSwing 组件请于 http:/ 下载public Main(final String url, final int maxWidth, final int maxHeight) super(new BorderLayou
18、t();JPanel webBrowserPanel = new JPanel(new BorderLayout();final String fileName = System.currentTimeMillis() + “.jpg“;final JWebBrowser webBrowser = new JWebBrowser(null);webBrowser.setBarsVisible(false);webBrowser.navigate(url);webBrowserPanel.add(webBrowser, BorderLayout.CENTER);add(webBrowserPan
19、el, BorderLayout.CENTER);JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 4);webBrowser.addWebBrowserListener(new WebBrowserAdapter() / 监听加载进度public void loadingProgressChanged(WebBrowserEvent e) / 当加载完毕时if (e.getWebBrowser().getLoadingProgress() = 100) String result = (String) webBrow
20、ser.executeJavascriptWithResult(jsDimension.toString();int index = result = null ? -1 : result.indexOf(“:“);NativeComponent nativeComponent = webBrowser.getNativeComponent();Dimension originalSize = nativeComponent.getSize();Dimension imageSize = new Dimension(Integer.parseInt(result.substring(0, in
21、dex), 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, B
22、ufferedImage.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()
23、;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(fileName); catch (IOE
24、xception ex) ex.printStackTrace();/ 退出操作System.exit(0););add(panel, BorderLayout.SOUTH);public static void main(String args) NativeInterface.open();SwingUtilities.invokeLater(new Runnable() public void run() / SWT 组件转 Swing 组件,不初始化父窗体将无法启动 webBrowserJFrame frame = new JFrame(“以 DJ 组件保存指定网页截图“);/ 加载指
25、定页面,最大保存为 640x480 的截图frame.getContentPane().add(new Main(“http:/ 640, 480),BorderLayout.CENTER);frame.setSize(800, 600);/ 仅初始化,但不显示frame.invalidate();frame.pack();frame.setVisible(false););NativeInterface.runEventPump();上一篇:吾辈正式加入 Twitter 一族了 下一篇:浅谈 JavaSE 性能优化(1)BufferedImage 与像素级渲染 查看评论 * 以上用户言论只代
26、表其个人观点,不代表 CSDN 网站的观点或立场个人资料 cping1982访问:810576 次 积分:6561 分 排名:第 170 名 原创:304 篇 转载:65 篇 译文:3 篇 评论:4291 条 文章搜索 文章分类 JAVA应用(73) JAVA 游戏开发(50) 原创小说(51) 技术文章(56) 杂文杂记(42) 转载文章(7) 文章存档 2011 年 07 月(1)2011 年 06 月(1)2011 年 05 月(2)2011 年 03 月(1)2011 年 02 月(3)2011 年 01 月(2)2010 年 12 月(3)2010 年 11 月(3)2010 年 1
27、0 月(2)2010 年 09 月(2)2010 年 08月(7)2010 年 07 月(1)2010 年 06 月(1)2010 年 05 月(3)2010 年 04 月(3)2010 年 03 月(10)2010年 02 月 (16)2010 年 01 月(14)2009 年 12 月(7)2009 年 11 月(11)2009 年 10 月(29)2009 年 09月(5)2009 年 08 月(4)2009 年 06 月(12)2009 年 05 月(7)2009 年 04 月(5)2009 年 03 月(5)2009年 02 月 (10)2009 年 01 月(3)2008 年 12
28、 月(10)2008 年 11 月(9)2008 年 10 月(2)2008 年 09 月(6)2008 年 08 月(11)2008 年 06 月(21)2008 年 05 月(21)2008 年 04 月(16)2008 年 03 月(16)2008 年 02 月(16)2008 年 01 月(8)2007 年 12 月(15)2007 年 11 月(7)2007 年 10 月(15)2007年 09 月 (7)2007 年 08 月(12)2007 年 07 月(2)2007 年 06 月(4) 阅读排行 ExtJS2.0 开发与实践笔记 0. (27553) 浅谈 2011 年上半年
29、Java 游戏领域动态 (21975) 未睹棺椁先哭君谷歌墓志铭 (21656) Android 游戏框架 Libgdx 使用入. (16635) Java&.Net 虚拟机精简 (Green. (15973) 中国本土化编程(汉语编程 )之我见 (14608) 浅谈 java.util.concurre. (14418) 对编程语言的“自以为是”排名 (14200) Android 游戏开发示例弹幕+战棋 (13748) 或许您还不知道的八款 Android 开源游. (13045) 评论排行后辈悼王江民先生文(文言文) (236) 未睹棺椁先哭君谷歌墓志铭 (192) LGame 框架问题
30、汇总,有疑问请发至此文 (187) 有了 HTML5,Flash 还能走多远? (173) 谈谈最近的 Oracle 与 Google 之争 (155) Java 游戏开发框架 LGame-0.2 (152) LGame-0.3(Android 与 Ja. (125) 中国本土化编程(汉语编程 )之我见 (101) Android 及 JavaSE 游戏引擎 LG. (91) LGame(Android 版)开发示例之. (91) 最新评论请教个问题,使用 0.3.1 包里. 额,我下 LGame,在我机子上. 鹏大,小弟看用 LGame 写了个. 鹏大最近忙什么呢? 很久没见你. 请问下,如
31、果用你的引擎,地图编. 有个问题请教一下。meshTe. 怎么学的那么好啊! /* * 渲染纹理为指定状 . 2.96 中使用声音的时候,有多. 支持新版本。 Java 的 PC 游戏开发人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)0 月晕础润人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)1风云初现人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)2踏破红尘人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)3邯郸学步人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)4一步莲华人生如梦游戏间,RPG 游戏开源开发讲座(JAVA 篇)5一树双花人生如梦游戏间
32、,RPG 游戏开源开发讲座(JAVA 篇)6走马观花人生如梦游戏间,JAVA 游戏开源开发讲座番外篇之 AVG 开发皮影史上最扯 Java 图形绘制(J2SE)之一 JAVA 动画效果JAVA 中 人工无脑 系统(chatbot)的实现JAVA 图形操作中 FPS 的计算(附带随机生成乱数球体用例)JAVA 实现拼图游戏Java伪寻径追踪实现Java 仿太阁立志传 5Java 汉诺塔测试Java 模拟桌球打击处理及绘制Java 制作的类祖码游戏-数字祖码Java 中 2.5D 游戏(斜 45 度角)的设计与实现(1)Java 中 2.5D 游戏(斜 45 度角)的设计与实现(2)Java 实现
33、窗体中角色逐渐风化效果Java 来做马里奥0让精灵再次舞动Java 来做马里奥1木叶传承Java 中的 A*(A star)寻径实现Java 来做马里奥2食不厌精Java 来做马里奥3杂兵登场Java 版吃豆游戏Java 炸弹人实现及源码Java 仿雷电及其源代码Java 桌面游戏巡礼ShadeJava 桌面游戏巡礼Java 数独Java 版 SLG 游戏开发入门0-让绘制的窗口响应鼠标事件Java 版 SLG 游戏开发入门1-关于本系列沉寂的国人开源项目 newxy(新坐标)web 框架Hocate web frameworkweb 框架Loonframework-DAO持久层框架Loonf
34、ramework-GAME游戏框架,尚未发布redlion(web 框架)Loonframework-WEBweb 框架,尚未发布myseelite(p2p 流媒体系统,c+项目)bo-blog(blog 系统,php 项目)opencrx(crm 系统)袋鼠 egg(服务器)DockPanel Suite Microsoft .NET Framework Winform UILuntbuild(软件管理工具)x2blog( 博客系统)magike(php 博客)YOYOPlayer(音乐播放器)经典 Blog# gzfqh 的专栏 底层代码研究(病毒及汇编) (RSS)# java 3D 游
35、戏编程 (RSS)Struts 框架应用网络安全圈子Struts 框架应用 千里冰封JAVA 浓香四溢ApoGames(德国某人的 Java 游戏作品展示)王大夫的颈椎病治疗博客枕善居,国内知名的 VB 及 VB.NET 资源博客爱枣报Peigen 的个人 blog (RSS)经典站点 JAVA 开源大全Java 爱好者Struts 标签文档数据库专区IBM 中国站SUN 中国社区中国 IT 实验室GoogleJavaGame 开发论坛提供 JSP,Servlets,Struts 以及 JSF 等技术支持一个海量的 JSF 资料聚合站SUN知名的 Java 开源项目集合站java2s区域黑客,
36、每天公布各国被黑的网站黑客手册技术论坛看雪软件安全论坛偶的其它应用实例 Java 中的 A*(A star)寻径实现Java 中将 byte转为 Blob 对象浅谈 Java 集合中 Array(数组)的应用Java 中 Image 翻转操作Java 中 DAO 的实现Java 获得系统环境变量C#将图像文件压缩为 AVI 文件播放C#转换 AVI 文件为 BMP 文件JAVA 实现可设置背景的 MDI 窗口在 Swing 中使用 Html 标签在 JTable 中加载进度条及进行操作SWT 行,AWT/Swing 也行系列(1)- 实现半透明及不规则窗体在 SWT 中使用 ChartDire
37、ctorJava 实现类 Windows 导航栏Java 自定义 JSlider UIJavaFx 实现 (2)-随机图形绘制JavaFx 实现 (1)-渐变效果浅谈 java.util.concurrent 包的并发处理Java 实现任意文件在 bmp 中的隐藏与导出ResultSet 转为实体对象通过 exe 启动 classJava 图形程序水纹倒映效果Java 图形程序中的对话逐字显示实现Java 音乐播放类JAVA 图形操作类JAVA 线程池的简单实现及优先级设置JAVA 版 JAVA IDE 环境(源码)ClassLoader 调用外部 jar 包Java 正则表达式入门ExtJS
38、2.0 开发与实践笔记0初识 ExtJSExtJS2.0 开发与实践笔记1ExtJS 中的 Dialog 与 FormExtJS2.0 开发与实践笔记2Ext 中的 LayoutExtJS2.0 开发与实践笔记3Ext 中的 Menu偶的文章百度对“十进制网络”的官方态度从珊瑚虫事件,看为什么中国出不了比尔.盖茨灭了珊瑚虫,下一个是谁?中国本土化编程(汉语编程 )之我见浅谈命名规范纯属强辩耻民对 Hibernate 使用之愚见对 Java(J2SE PC)开发之怪现象之我见国产开源项目的七宗罪叹今人无气节而作歌三国以后有几国论番茄花园的倒掉率性而作无题歌一首佛与专家消费者反映鸡蛋难吃后的 37 种回答方法打油诗我的梦想(御宅族之梦)Java 游戏开发中应始终坚持的 10 项基本原则别争了!原来微点遭遇的是自然灾害!微点。赢乎?输耶? 绿藻绕坝水冲去,无题文章风吹来为大众而写的程序员小说从简单易懂的现代魔法说开去浅论绿坝的四大优点