/**在这里贴上我注释满满的代码 求一语道破 求建议 求批评
没有贴main 方法 随便写个main方法便可运行 */
`
package com.subimaga;
import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import com.sun.awt.AWTUtilities;
public class ScreenCapture extends JFrame implements MouseListener,
MouseMotionListener {
private BufferedImage bufferedImage = null;// 用来存放图像
// 获取屏幕的大小
private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private int height = Toolkit.getDefaultToolkit().getScreenSize().height;
private Point point = new Point(0, height); // 截图的左上角
private Point point2 = new Point(0, 0);// 截图右下角
private Point point3 = new Point(0, 0);// 用来处理point 与point2 的关系
// 是画笔的透明度可控制
private AlphaComposite composite;
boolean isStarCut = false, isEndCut = false;// isStarCut 为开始选区
// isEndCut为截图结束仅标记结束选区
public ScreenCapture() {
// 初始化窗口
this.InitScr();
}
private void InitScr() // 初始化
{
// 截取整个桌面作为窗口的背景
try {
bufferedImage = new Robot().createScreenCapture(new Rectangle(0, 0,
width, height));
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 去掉窗体结构
this.setUndecorated(true);
// 设置窗体大小
this.setSize(width, height);
// 设置画笔的透明度
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f);
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setVisible(true);
this.setAlwaysOnTop(true);
repaint();
}
public void paint(Graphics g) {
// 配置截图环境
BufferedImage buff = new BufferedImage(width, height,
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = buff.createGraphics(); // 画笔一
Graphics2D g3 = buff.createGraphics(); // 画笔二 用两个画笔主要是因为需要不同的透明度
g2.drawImage(bufferedImage, 0, 0, null);
g2.setColor(Color.gray);
g2.setComposite(composite);
g2.fillRect(0, 0, width, height);
// 截图的工作
if (isStarCut == true || isEndCut == true) { // 当
confirmArea(); // 处理坐标的方法
/**
* 我实现的原理是 在铺了全屏截图的窗口上铺上一层灰色 透明为0.6 的实心矩形
* 根据用户在窗口拖动的坐标再另外截取一张相对应的图片铺在上面
*/
g3.drawImage(bufferedImage.getSubimage(point.x, point.y, Math
.abs(point2.x - point.x), Math.abs(point2.y - point.y)),
point.x, point.y, null);
// 画出一个绿色的空心矩形
g3.setColor(Color.green);
g3.drawRect(point.x, point.y, point2.x - point.x, point2.y
- point.y);
}
// 功能框的显示
if (isEndCut == true) { // 当选区结束 才会绘出此框
action();
// 背景框
g2.fillRect(point3.x, point3.y + 5, 200, 30);
g2.setColor(Color.red);
// 完成
g3.drawRect(point3.x, point3.y + 5, 60, 30);
g3.setColor(Color.white);
g3.drawString("完成", point3.x + 20, point3.y + 25);
// 重截
g2.drawRect(point3.x + 70, point3.y + 5, 60, 30);
g2.drawString("重截", point3.x + 20 + 70, point3.y + 25);
// 退出
g2.drawRect(point3.x + 140, point3.y + 5, 60, 30);
g2.drawString("退出", point3.x + 20 + 140, point3.y + 25);
}
// 双缓冲
g.drawImage(buff, 0, 0, this);
}
// 调节功能框位置的方法
public void action()
{
if (point2.x <= width - 200 && point2.y < height - 35) {
point3.x = point2.x;
point3.y = point2.y;
} else if (point.x >= 200 && point.y >= 35) {
point3.x = point.x;
point3.y = point.y - 50;
}
else if (point.x <= 200 && point2.x >= width - 200 && point.y >= 35) {
point3.x = point2.x - 205;
point3.y = point.y - 50;
} else if (point.y >= 35 && point2.y <= height - 35
&& point2.x >= width - 200) {
point3.x = point2.x;
point3.y = point2.y;
} else {
point3.x = point2.x - 205;
point3.y = point.y;
}
}
public void confirmArea() {
int temp;
point.x = point3.x; // 每一次开始都是和原点坐标比较
point.y = point3.y;
if (point2.x < point.x && point2.y < point.y) {
temp = point.x;
point.x = point2.x;
point2.x = temp;
temp = point.y;
point.y = point2.y;
point2.y = temp;
} else if (point2.x < point.x) {
temp = point.x;
point.x = point2.x;
point2.x = temp;
} else if (point2.y < point.y) {
temp = point.y;
point.y = point2.y;
point2.y = temp;
}
}
public void actoinCut(MouseEvent e) // 操作功能框的方法
{
if (isEndCut) {
// 完成
if (e.getX() >= point3.x && e.getX() <= point3.x + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
// //将截好的图保存起来 原理是利用点下完成的“按钮”时的坐标 即是最后一次决定的选区 对图片进行截图保存
try {
ImageIO.write(bufferedImage.getSubimage(point.x, point.y,
Math.abs(point2.x - point.x), Math.abs(point2.y
- point.y)), "jpg", new File("D:/D.jpg"));
} catch (IOException e1) {
// // TODO Auto-generated catch block
e1.printStackTrace();
}
;
System.exit(0); // 保存完毕马上退出 这里的保存够工作有点简单因为只是用来测试此截图工具的bug
// 具体的功能先不实现先
}
// 重截
else if (e.getX() >= point3.x + 70
&& e.getX() <= point3.x + 70 + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
isEndCut = false; // 重新截图 一切进入初始状态 这个 重截一直搞不好 求大神
isStarCut = false;
// 点击重截后鼠标依然保持手型样式 所以要恢复默认
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
// 重绘
repaint();
}
// 退出
else if (e.getX() >= point3.x + 140
&& e.getX() <= point3.x + 140 + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
System.exit(0);
}
}
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if (e.getButton() == MouseEvent.BUTTON3) // 双击 右键退出程序
{
if (e.getClickCount() == 2)
System.exit(0);
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
// 只有当初始化状态才生效
if (isStarCut == false && isEndCut == false
&& e.getButton() == MouseEvent.BUTTON1) {
point.x = e.getX();
point.y = e.getY();
point3.x = e.getX();
point3.y = e.getY();
isStarCut = true;
}
// 进入重截的条件
else if (isEndCut) {
this.actoinCut(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
// 截图开始生效
if (isStarCut && isEndCut == false
&& e.getButton() == MouseEvent.BUTTON1) {
isEndCut = true; // 鼠标一放开马上标记截图结束
isStarCut = false; // 重新标记未开始选区状态
repaint();// 重绘
}
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
// 拖动是改变矩形的坐标点
if (isStarCut || isEndCut) {
point2.x = e.getX();
point2.y = e.getY();
repaint();
}
}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
// 在功能框上显示手型状态
if (isEndCut) {
// 完成
if (e.getX() >= point3.x && e.getX() <= point3.x + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
// 重截
else if (e.getX() >= point3.x + 70
&& e.getX() <= point3.x + 70 + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
// 退出
else if (e.getX() >= point3.x + 140
&& e.getX() <= point3.x + 140 + 60
&& e.getY() >= point3.y + 5 && e.getY() <= point3.y + 35) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
} else {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
}
}