核心代码为:snapShot方法中的相关逻辑
package Jietu
import java.awt.Dimension
import java.awt.Rectangle
import java.awt.Robot
import java.awt.Toolkit
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
public class CameraTest {
private String filePreStr// 默认前缀(选择存储路径例如: D:\\)
private String defName = "cameraImg" // 默认截图名称
static int serialNum = 0 //截图名称后面的数字累加
private String imageFormat// 图像文件的格式
private String defaultImageFormat = "png"//截图后缀
Dimension d = Toolkit.getDefaultToolkit().getScreenSize()//获取全屏幕的宽高尺寸等数据
public CameraTest() {
filePreStr = defName
imageFormat = defaultImageFormat
}
public CameraTest(String s, String format) {
filePreStr = s
imageFormat = format
}
public void snapShot() {
try {
// *** 核心代码 *** 拷贝屏幕到一个BufferedImage对象screenshot
BufferedImage screenshot = (new Robot()).createScreenCapture(new Rectangle(0, 0, (int) d.getWidth(), (int) d.getHeight()))
serialNum++
// 根据文件前缀变量和文件格式变量,自动生成文件名
String name = filePreStr + String.valueOf(serialNum) + "." + imageFormat
File f = new File(name)
System.out.print("Save File " + name)
// 将screenshot对象写入图像文件
ImageIO.write(screenshot, imageFormat, f)
System.out.print("..Finished!\n")
} catch (Exception ex) {
System.out.println(ex)
}
}
// 运行之后,即可将全屏幕截图保存到指定的目录下面<br>// 配合前端页面上面的选择尺寸等逻辑,传到后台,即可实现自由选择截图区域和大小的截图<br>
public static void main(String[] args) {
CameraTest cam = new CameraTest("d:\\Hello", "png")//
cam.snapShot()
}
}
主要是利用java的几个先有的函数,如Robot这个类的一个方法createScreenCapture一个获得一个任意大小的屏幕图像(在这里是全屏图像),而所谓的截图就是在这个图像上画出一个矩形,再利用上面的方法获得这部分的图像,程序中的cf.setAlwaysOnTop(true)是必需的看起来是在屏幕上截图,其实只是在一个在一个内镶有桌面背景的JFrame中截图。不知道还有没有其他的好方法~附上代码:
import java.awt.*
import java.awt.image.*
import java.awt.event.*
import java.io.File
import javax.imageio.ImageIO
import javax.swing.*
public class Camera {
/**
* @param args
*/
public static void main(String[] args) {
CameraJFrame cf=new CameraJFrame()
cf.setAlwaysOnTop(true)
cf.setUndecorated(true)
cf.setVisible(true)
}
}
class CameraJFrame extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 1L
Dimension di=Toolkit.getDefaultToolkit().getScreenSize()
public CameraJFrame()
{
setSize(di)
getContentPane().add(new CameraJPanel())
}
class CameraJPanel extends JPanel implements MouseListener,MouseMotionListener
{
/**
* flag主要是用来判别状态。
* 文件的格式名是unname+数字编号,格式是png
*/
private static final long serialVersionUID = 1L
BufferedImage bi,get
int startx,starty,endx,endy
int flag=1
String filename="unname"
String fileformat="png"
int count=1
public CameraJPanel()
{
try
{
Robot ro=new Robot()
bi=ro.createScreenCapture(new Rectangle(0,0,di.width,di.height))
}
catch(Exception e)
{
e.printStackTrace()
}
addMouseListener(this)
addMouseMotionListener(this)
}
public void paintComponent(Graphics g)
{
g.drawImage(bi,0,0,di.width,di.height,this)
g.setColor(Color.red)
g.drawRect(startx, starty, endx-startx, endy-starty)
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(e.getButton()==MouseEvent.BUTTON3)
{
System.exit(0)
}
else if(e.getClickCount()==2)
{
try
{
Robot ro=new Robot()
get=ro.createScreenCapture(new Rectangle(startx,starty,endx-startx,endy-starty))
String name=filename+String.valueOf(count++)+"."+fileformat
File f=new File(name)
ImageIO.write(get, fileformat, f)
}
catch(Exception ex)
{
ex.printStackTrace()
}
flag=1//置flag为1,以便重新开始截图。
startx=starty=endx=endy=0
repaint()
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
if(flag==1)
{
startx=e.getX()
starty=e.getY()
}
}
public void mouseReleased(MouseEvent e) {
flag=0
}
public void mouseDragged(MouseEvent e) {
flag=1
endx=e.getX()
endy=e.getY()
repaint()
}
public void mouseMoved(MouseEvent e) {}
}
}
事实上,如果您想以Java实现网页截图,也就是“输入一段网址,几秒钟过后就能截取一张网页缩略图”的效果。那么,您至少有3种方式可以选择。
1、最直接的方式——使用Robot
方法详解:该方法利用Robat提供的强大桌面 *** 作能力,硬性调用浏览器打开指定网页,并将网页信息保存到本地。
优势:简单易用,不需要任何第三方插件。
缺点:不能同时处理大量数据,技术含量过低,属于应急型技巧。
实现方法:使用如下代码即可。
[java] view plaincopypublic static void main(String[] args) throws MalformedURLException,
IOException, URISyntaxException, AWTException {
//此方法仅适用于JdK1.6及以上版本
Desktop.getDesktop().browse(
new URL("http://google.com/intl/en/").toURI())
Robot robot = new Robot()
robot.delay(10000)
Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize())
int width = (int) d.getWidth()
int height = (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, height, null)
//保存图片
ImageIO.write(bi, "jpg", new File("google.jpg"))
}
2、最常规的方式——利用JNI,调用第三方C/C++组件
方法详解:目前来讲,Java领域对于网页截图组件的开发明显不足(商机?),当您需要完成此种 *** 作时,算得上碰到了Java的软肋。但是,众所周知Java也拥有强大的JNI能力,可以轻易将C/C++开发的同类组件引为己用。不懂可以扣五七八零二四一四四
优势:实现简单,只需要封装对应的DLL文件,就可以让Java实现同类功能。
劣势:同其他JNI实现一样,在跨平台时存在隐患,而且您的程序将不再属于纯Java应用。
实现方法:可参见此用例,具体封装何种C/C++组件请自行选择。
PS:示例来源于ACA HTML to Image Converter项目(http://www.acasystems.com/en/web-thumb-activex/faq-convert-html-to-image-in-java.htm ),这是一个收费的HTML转Image第三方组件,但封装方式在Java中大同小异。
引用JNI封装:
[java] view plaincopyimport sun.awt.*
import java.awt.*
import javax.swing.*
import java.awt.event.*
import java.awt.*
import java.awt.peer.*
public class Snap
{
static
{
System.loadLibrary("Snap")
}
public static void main( String[] argv )
{
Snap t_xSnap = new Snap()
t_xSnap.Start("http://www.google.com", "snapshot-google.png")
}
public native void Start(String pi_strURL, String pi_strImageName)
}
CPP部分的实现:
[java] view plaincopy
#include <windows.h>
#include <atlbase.h>
#include "snap.h"
#pragma comment(lib,"atl.lib")
#import "./../../acawebthumb.dll" no_namespace
JNIEXPORT 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_Converter.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标记,并将其图像化
方法详解:众所周知,HTML之所以在浏览器中以具体的网页格式出现,并非服务器端传了一整个应用到客户端,而是源自于浏览器对于客户端自行解析的结果。因此,只要我们将对应的解析一一实现,那么将网页图形化,就将不是什么难事。
优势:纯Java实现,一劳永逸,一旦开发完成则永远通用,而且有一定的商用价值。
劣势:开发费时,且需要针对不同语法做精确分析,才能保证输出的基本正确。尤其在涉及到JavaScript解析时,难度将尤其增大。
实现方法:目前尚无具体案例可供参考。但是,由于Java有jdic之类的浏览器项目存在(https://jdic.dev.java.net/),而Java图形界面又属绘制生成。从理论上说,我们可以将所有具备Graphics的组件图形化保存。
而如果自行解析,那么您需要建立HTML解析器(或使用第三方的,万幸Java在这方面的组件很多),了解Java2D机制,了解何时该使用drawString绘制文字,何时又该使用drawImage插入图片等等。
谢谢采纳!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)