基于java的截图工具

来源:互联网 时间:1970-01-01

随手翻了以前写的小程序,发现截图工具是一个挺有趣的程序.

因为之中有许多小细节和图像的处理. 下面将它们列出来.

程序中包括主要类有: 主界面DesktopCapture,截图功能类CaptureView,辅助类ImagePanel以及托盘类MyTray

 

1. 首先是获得桌面的截图,由DesktopCapture中的按钮触发,这里使用java.awt.Robot来获取.

//获得屏幕图片(desktopImg是一个BufferedImage类型的成员变量)

    public void captureDesktop() throws Exception{

        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

        Rectangle rect = new Rectangle(d);

        desktopImg = new BufferedImage((int)d.getWidth(),(int)d.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);

        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();

        GraphicsDevice device = environment.getDefaultScreenDevice();        Robot robot = new Robot(device);
        desktopImg = robot.createScreenCapture(rect);

}  


 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(Graphics g)

 

    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<x2 && y1<y2)
            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下载

/Files/mailingfeng/Easy截图v1.3-MAI.rar 


相关阅读:
Top