14 screenShotLikeQQ

来源:互联网 发布:淘宝刷单被骗案例 编辑:程序博客网 时间:2024/05/17 02:11

前言

根据上一篇播客的博主的播客, 我发现了 博主有很多swing相关的播客, 就没事 看了一看, 闲来蛋疼 就参考着做了一些有意思的案例, so ..
此代码参考了 一些该博主的一些swing相关技巧

问题描述

做一个截图工具, 要求如下, 在程序启动之后 截取当前屏幕的状态, 然后 用户选择需要截取的部分, 用户在选择的图片之上双击之后, 将其保存到剪切板

思路

思路 : 截图 使用robot截图, 绘制用户选中区域使用swing相关控件, 拖拽的时候 更新该控件的坐标 以及新位置的截取的图片

难点 : 1 对于swing的一些效果的掌握, 比如 全屏, 方格效果等等
2 对于用户是否更新截取部分的逻辑的处理
3 对于用户拖拽截取部分 越界的处理

其余部分, 请详见代码

参考代码

/** * file name : Test14QQSnapShot.java * created at : 9:28:54 PM Nov 24, 2015 * created by 970655147 */package com.hx.test08;// 仿qq截图public class Test14QQSnapShot extends JFrame {    // 参考 : http://blog.csdn.net/ycb1689/article/details/8017396    // robot [截图]    private static Robot robot;    static {        try {            robot = new Robot();        } catch (AWTException e) {            e.printStackTrace();        }    }    // 背景色, 整个屏幕的大小    // 存放当前屏幕图片的label, 存放截取的部分图片的label, 存放截取部分图片的ImageIcon    private Color bgColor = new Color(200,150,150);    private Dimension screenSize;    private JLabel label;    private JLabel subImg;    private ImageIcon subImgIcon;    // 初始化        // 1. 配置当前JFrame        // 2. 添加元素        // 3. 为当前JFrame配置KeyListener, 配置退出当前程序的按键        // 4. 配置当前JFrame的MouseListener, 用于控制鼠标的相应操作    public Test14QQSnapShot() {        setLayout(null);        setDefaultCloseOperation(EXIT_ON_CLOSE);        setSize(getScreenSize() );        setExtendedState(MAXIMIZED_BOTH);        setResizable(false);        // 这里不将其设置为top窗口的目的是为了多次截图//      setAlwaysOnTop(true);        setUndecorated(true);        setTitle("snapshot");        // subImg 需要放到全屏幕截图的label的前面        // 获得整个屏幕的截图        final BufferedImage allScreenImg = robot.createScreenCapture(new Rectangle(0, 0, getScreenSize().width, getScreenSize().height));        subImg = new JLabel();        subImg.setBorder(BorderFactory.createLineBorder(Color.GREEN, 2) );        subImgIcon = new ImageIcon();        subImg.setIcon(subImgIcon);        MouseAdapter dragAdpater = new SubImageAdapter(subImg, subImgIcon, allScreenImg);        subImg.addMouseListener(dragAdpater);        subImg.addMouseMotionListener(dragAdpater);        add(subImg);        label = new JLabel(){              protected void  paintComponent(Graphics g) {                     super .paintComponent(g);                     g.drawImage(allScreenImg, 0, 0, this);                     Graphics2D g2d  =  (Graphics2D) g;                     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);                     g2d.setColor(bgColor);                     // fill的时候, 使用的色度                     AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 40 /100.0F );                     g2d.setComposite(composite);                     g2d.fill(new RoundRectangle2D.Float(0, 0, this .getWidth(), this.getHeight(), 0, 0 ) );              }        };        label.setBounds(0, 0, getWidth(), this.getHeight());        add(label);        // 保证截图的时候, 不会截到"Test14QQSnapShot"的窗口, 而是当前状态屏幕的窗口        setVisible(true);        // for 'esc' exit        addKeyListener(new KeyListener() {            public void keyTyped(KeyEvent e) {            }            public void keyReleased(KeyEvent e) {            }            public void keyPressed(KeyEvent e) {                if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {                    Test14QQSnapShot.this.dispose();                    System.exit(0);                }            }        });        MouseAdapter adapter = new ScreenShotDragMouseAdapter(this, allScreenImg);        addMouseListener(adapter);        addMouseMotionListener(adapter);    }    // main    public static void main(String []args) {        new Test14QQSnapShot();    }    // 获取整个屏幕的大小    private Dimension getScreenSize() {        if(screenSize == null) {            screenSize = Toolkit.getDefaultToolkit().getScreenSize();        }        return screenSize;    }    // 部分截图的MouseAdpater    static class ScreenShotDragMouseAdapter extends MouseAdapter {        // 整个屏幕的截图, 截取的部分截图, 是否截取过图片, 是否开始截取部分图片        // 截取开始的坐标        private Test14QQSnapShot parentFrame;        private BufferedImage allScreenImg;        private boolean isCuted;        private boolean isStart;        private Point start = new Point();        private Dimension dimen = new Dimension();        // 初始化        public ScreenShotDragMouseAdapter(Test14QQSnapShot  parentFrame, BufferedImage allScreenImg) {            this.parentFrame = parentFrame;            this.allScreenImg = allScreenImg;        }        // 1. 如果截过图, 判断当前点击的点是否在原截图的方框之中             // 如果在, 则不能重新截图[需要拖动该图 [SubImgMouseAdapter] ]            // 否则, 更新标志变量重新截图        // 2. 记录start        @Override        public void mousePressed(MouseEvent e) {            if(isCuted ) {                java.awt.Point pointNow = new java.awt.Point(e.getX(), e.getY());                if(! isPointInRect(pointNow, parentFrame.subImg.getLocation(), parentFrame.subImg.getSize()) ) {                    isCuted = false;                }            }            if(! isCuted) {                start.x = e.getX();                start.y = e.getY();            }        }        // 记录dimen        @Override        public void mouseReleased(MouseEvent e) {            if(! isCuted) {                isCuted = true;                dimen.width = e.getX() - start.x;                dimen.height = e.getY() - start.y;            }        }        // 如果没有结果图 [isCuted在MouseRelease中更新]            // 获取当前截图的start, dimen[如果 dimen.width 或者dimen.height 小于0, 则更新start, dimen[更新为符合条件[dimen.width & dimen.height 大于0]的等价表示] ]            // 然后  判断截图的部分是否超出边界, 以及dimen.width 或者dimen.height 可能为0, 如果校验通过, 进行截图, 更新parentFrame.subImgIcon, 以及parentFrame.subImg.location        @Override        public void mouseDragged(MouseEvent e) {            if(! isCuted) {                Dimension dimenNow = new Dimension();                dimenNow.width = e.getX() - start.x;                dimenNow.height = e.getY() - start.y;                int startX = start.x, startY = start.y;                if(dimenNow.width < 0) {                    dimenNow.width = (- dimenNow.width);                    startX -= dimenNow.width;                }                if(dimenNow.height < 0) {                    dimenNow.height = (- dimenNow.height);                    startY -= dimenNow.height;                }                if((startX + dimenNow.width < parentFrame.getScreenSize().getWidth()) && (startY + dimenNow.height < parentFrame.getScreenSize().getHeight()) && (dimenNow.width > 0) && (dimenNow.height > 0) ) {                    parentFrame.subImgIcon.setImage(allScreenImg.getSubimage(startX, startY, dimenNow.width, dimenNow.height) );                    parentFrame.subImg.setBounds(startX, startY, dimenNow.width, dimenNow.height);                }            }        }        // 判断给定的点是否在给定的矩形内        private boolean isPointInRect(java.awt.Point pos, java.awt.Point start, Dimension dimen) {            return (pos.x > start.x) && (pos.y > start.y) && (pos.x < start.x + dimen.width) && (pos.y < start.y + dimen.height);        }    }    // 拖拽的MouseListener    public class SubImageAdapter extends MouseAdapter {        // 操作的frame, 整个屏幕的截图        private Component subImg;        private BufferedImage allScreenImg;        private int lastX = -1;        private int lastY = -1;        // 初始化        public SubImageAdapter(Component subImg, ImageIcon subImgIcon, BufferedImage allScreenImg) {            super();            this.subImg = subImg;            this.allScreenImg = allScreenImg;        }        // 记录拖拽之前点击的坐标        @Override        public void mousePressed(MouseEvent e) {            lastX = e.getX();            lastY = e.getY();        }        // 判断拖拽之后元素是否超出屏幕            // 如果没有, 则进行更新截图subImgIcon.img, 更新subImg.location        @Override        public void mouseDragged(MouseEvent e) {            java.awt.Point start = subImg.getLocation();            Dimension dimen = subImg.getSize();            start.x += e.getX() - lastX;            start.y += e.getY() - lastY;            start.x = start.x > 0 ? start.x : 0;            start.y = start.y > 0 ? start.y : 0;            start.x = (start.x + dimen.width < getScreenSize().getWidth() ) ? start.x : ((int) getScreenSize().getWidth() - dimen.width);            start.y = (start.y + dimen.height < getScreenSize().getHeight() ) ? start.y : ((int) getScreenSize().getHeight() - dimen.height);            subImg.setLocation(start );            subImgIcon.setImage(allScreenImg.getSubimage(start.x, start.y, dimen.width, dimen.height) );        }        // 进行保存图片到剪切板的操作, 并更新subImg, 以便于下一次截图        @Override        public void mouseClicked(MouseEvent e) {            if(e.getClickCount() > 1) {                Tools.copyImgToClipBoard((RenderedImage) subImgIcon.getImage() );                subImg.setSize(0, 0);            }        }    }}

效果截图

这里写图片描述

总结

小工具, 扯扯淡, 向原作者致敬 !

参考 :
http://blog.csdn.net/ycb1689/article/details/8017396

注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!

0 0
原创粉丝点击