源码百度盘备份:http://pan.baidu.com/s/1o69PoDG
随手翻了以前写的小程序,发现截图工具是一个挺有趣的程序.
因为之中有许多小细节和图像的处理. 下面将它们列出来.
程序中包括主要类有:主界面DesktopCapture,截图功能类CaptureView,辅助类ImagePanel以及托盘类MyTray
1.首先是获得桌面的截图,由DesktopCapture中的按钮触发,这里使用java.awt.Robot来获取.
public class CaptureView extends JWindow implements MouseListener,KeyListener,MouseMotionListener{
private static final long serialVersionUID = 1L;
private BufferedImage desktopImg;
private boolean captured = false ,draging = false , toolPanelAtRight = true;
private int x = 0 , y = 0 ,x1 = 0 , y1 = 0 , x2 = 1 , y2 = 1; // 坐标原点坐标,选区左上角和右下角坐标
private int point_x , point_y; // 鼠标点坐标
private Color point_color; // 鼠标点颜色
private DesktopCapture window; // 所属截图工具主窗体
private ImagePanel toolPanel; // 提示整框
private final int TOOLPANEL_WIDTH = 200,TOOLPANEL_HEIGHT = 300 , HALF_PICK_IMG = 40;
private JTextArea infoArea ; // 提示区
private ToolImagePanel pickImgPanel; // 放大镜
CaptureView(DesktopCapture window , BufferedImage img){
super(window);
this.window = window;
this.desktopImg = img;
setSize(Toolkit.getDefaultToolkit().getScreenSize());
init();
setVisible( true);
setAlwaysOnTop( true);
this.requestFocus();
}
void init(){
this.setContentPane( new BackGroundPanel(desktopImg));
setLayout( null);
toolPanel = new ImagePanel("images/weixin_bg.jpg");
toolPanel.setLayout( new BorderLayout());
pickImgPanel = new ToolImagePanel();
infoArea = new JTextArea();
infoArea.setOpaque( false);
infoArea.setEditable( false);
infoArea.setForeground(Color.WHITE);
infoArea.setFont( new Font("楷体" , Font.PLAIN ,11 ));
infoArea.setText("");
toolPanel.add(pickImgPanel,BorderLayout.CENTER);
toolPanel.add(infoArea,BorderLayout.SOUTH);
toolPanel.setLocation(getWidth()-TOOLPANEL_WIDTH, 0);
toolPanel.setSize(TOOLPANEL_WIDTH,TOOLPANEL_HEIGHT);
this.getLayeredPane().add(toolPanel,300);
addKeyListener( this);
addMouseListener( this);
addMouseMotionListener( this);
}
2. 弹出截图窗口
A.将桌面截图desktopImg交给截图组件CaptureView处理.(CaptureView的作用主要是平铺屏幕图片,并显示于桌面的最顶层,然后让用户选择截图区域,具体实现有很多方式.)
B. 这里选择让CaptureView重写JWindow,主要代码部分包括以下几部分:桌面黑色蒙版,放大镜,坐标,鼠标点颜色,截图选区长和宽等提示
1). CaptureView的初始化
public class CaptureView extends JWindow implements MouseListener,KeyListener,MouseMotionListener{
private static final long serialVersionUID = 1L;
private BufferedImage desktopImg;
private boolean captured = false ,draging = false , toolPanelAtRight = true;
private int x = 0 , y = 0 ,x1 = 0 , y1 = 0 , x2 = 1 , y2 = 1; // 坐标原点坐标,选区左上角和右下角坐标
private int point_x , point_y; // 鼠标点坐标
private Color point_color; // 鼠标点颜色
private DesktopCapture window; // 所属截图工具主窗体
private ImagePanel toolPanel; // 提示整框
private final int TOOLPANEL_WIDTH = 200,TOOLPANEL_HEIGHT = 300 , HALF_PICK_IMG = 40;
private JTextArea infoArea ; // 提示区
private ToolImagePanel pickImgPanel; // 放大镜
CaptureView(DesktopCapture window , BufferedImage img){
super(window);
this.window = window;
this.desktopImg = img;
setSize(Toolkit.getDefaultToolkit().getScreenSize());
init();
setVisible( true);
setAlwaysOnTop( true);
this.requestFocus();
}
void init(){
this.setContentPane( new BackGroundPanel(desktopImg));
setLayout( null);
toolPanel = new ImagePanel("images/weixin_bg.jpg");
toolPanel.setLayout( new BorderLayout());
pickImgPanel = new ToolImagePanel();
infoArea = new JTextArea();
infoArea.setOpaque( false);
infoArea.setEditable( false);
infoArea.setForeground(Color.WHITE);
infoArea.setFont( new Font("楷体" , Font.PLAIN ,11 ));
infoArea.setText("");
toolPanel.add(pickImgPanel,BorderLayout.CENTER);
toolPanel.add(infoArea,BorderLayout.SOUTH);
toolPanel.setLocation(getWidth()-TOOLPANEL_WIDTH, 0);
toolPanel.setSize(TOOLPANEL_WIDTH,TOOLPANEL_HEIGHT);
this.getLayeredPane().add(toolPanel,300);
addKeyListener( this);
addMouseListener( this);
addMouseMotionListener( this);
}
2). 重写JWindow的paint(Graphicsg)
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLACK);
if(captured == true){
if(draging){
// 截图辅助十字线
g.drawLine(point_x, 0, point_x, getHeight());
g.drawLine(0, point_y, getWidth(), point_y);
}
confirmArea();//确定截图选区的左上角坐标(x1,y1)和右下角坐标(x2,y2)
if(x1
g.drawImage(desktopImg.getSubimage(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1)), x1, y1, null);
g.drawRect(x1,y1,Math.abs(x2-x1),Math.abs(y2-y1));
} else{
g.drawLine(point_x, 0, point_x, getHeight());
g.drawLine(0, point_y, getWidth(), point_y);
}
repaintToolPanel();//放大镜和提示框的重画ToolPanel
}
3). 截图选区的坐标的确定
复制代码
// 确定区域的左上点和右下角坐标
public void confirmArea(){
int temp;
// 以x,y为截图选区左上角坐标初值,计算左上角x1,y1和右下角x2,y2的坐标
x1 = x;
y1 = y;
if(x2 < x1){ // 2,3
if(y2 < y1){ // 2
temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
} else{ // 4
temp = x1;
x1 = x2;
x2 = temp;
}
} else{ // 1,4
if(y2 < y1){ // 1
temp = y1;
y1 = y2;
y2 = temp;
}
}
}
4).提示窗体的重绘,这里的"放大镜"使用鼠标位置上下40像素的屏幕截图区域图像进行5倍放大.采用背景重绘的JPanel显示
复制代码
// 提示框状态信息的刷新
public void refreshInfoText(){
// 文本信息
String text = new String("操作提示: By MaiLingFeng =^-^=\n1.单击托盘图标->进入截图状态\n2.双击右键------>退出截图状态\n3.双击左键------>保存截图\n4.单击右键---->重新选择截图区域");
String infoString;
int captureWidth,captureHeight;
if(captured == true){
captureWidth = x2 - x;
captureHeight = y2 - y;
} else{
captureWidth = 0;
captureHeight = 0;
}
infoString = "X,Y : " + point_x + "," + point_y + " W*H : " + captureWidth + "*" + captureHeight +
"\n当前RBG:(" + point_color.getRed() + "," + point_color.getGreen() + "," + point_color.getBlue() + ")\n" + text ;
infoArea.setText(infoString);
// 放大镜信息
int pick_x1 , pick_y1 , pick_x2 , pick_y2 , pickImg_x , pickImg_y ;
if(point_x - HALF_PICK_IMG < 0){ // 获得放大图片的捡取左上角和右下角坐标,以及在放大镜中的左上角位置坐标
pick_x1 = 0 ;
pick_x2 = point_x + HALF_PICK_IMG;
pickImg_x = HALF_PICK_IMG - point_x;
} else if( point_x + HALF_PICK_IMG > this.getWidth()){
pick_x1 = point_x - HALF_PICK_IMG;
pick_x2 = this.getWidth();
pickImg_x = 0;
} else{
pick_x1 = point_x - HALF_PICK_IMG;
pick_x2 = point_x + HALF_PICK_IMG;
pickImg_x = 0;
}
if(point_y - HALF_PICK_IMG <0){
pick_y1 = 0 ;
pick_y2 = point_y + HALF_PICK_IMG;
pickImg_y = HALF_PICK_IMG - point_y;
} else if(point_y + HALF_PICK_IMG > this.getHeight()){
pick_y1 = point_y - HALF_PICK_IMG ;
pick_y2 = this.getHeight();
pickImg_y = 0;
} else{
pick_y1 = point_y - HALF_PICK_IMG ;
pick_y2 = point_y + HALF_PICK_IMG;
pickImg_y = 0;
}
BufferedImage pickImg = new BufferedImage(HALF_PICK_IMG*2,HALF_PICK_IMG*2,BufferedImage.TYPE_INT_RGB);
Graphics pickGraphics = pickImg.getGraphics();
pickGraphics.drawImage(desktopImg.getSubimage(pick_x1, pick_y1, pick_x2 - pick_x1, pick_y2 - pick_y1), pickImg_x, pickImg_y, Color.black, null);
pickImgPanel.refreshImg(pickImg.getScaledInstance(TOOLPANEL_WIDTH, TOOLPANEL_WIDTH, BufferedImage.SCALE_AREA_AVERAGING));
toolPanel.validate();
}
5).效果图
6).可运行jar下载