当前位置:

首页 > 编程开发 > Java实现屏幕截图工具的代码怎么写

Java实现屏幕截图工具的代码怎么写

效果展示程序运行后的截图:先测试一下功能:截图过程对界面的捕捉:双击保存后的显示界面:后续的步骤就自己去尝试吧,这里给出了简单的测试过程。程序结构核心代码CaptureScreen.java类/***CaptureScreen.java*/importjava.awt.*;importjava.awt.datatransfer.DataFlavor;importjava.awt.datatransfer.Transferable;importjava.awt.datatransfer.Unsupporte

本文目录

    效果展示

    程序运行后的截图:

    Java实现屏幕截图工具的代码怎么写

    先测试一下功能:

    截图过程对界面的捕捉:

    Java实现屏幕截图工具的代码怎么写

    双击保存后的显示界面:

    Java实现屏幕截图工具的代码怎么写

    后续的步骤就自己去尝试吧,这里给出了简单的测试过程。

    程序结构

    Java实现屏幕截图工具的代码怎么写

    核心代码

    CaptureScreen.java类

    /**
     * CaptureScreen.java
     */
    import java.awt.*;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.*;
    import java.awt.image.*;
    
    public class CaptureScreen extends JFrame implements ActionListener {
        private JButton start,cancel;
        private JPanel c;
        private BufferedImage get;
        private JTabbedPane jtp;//一个放置很多份图片
        private int index;//一个一直会递增的索引,用于标认图片
        private JRadioButton java,system;//JAVA界面,系统界面
        /** Creates a new instance of CaptureScreen */
        public CaptureScreen() {
            super("屏幕截取");
            try{
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            }catch(Exception exe){
                exe.printStackTrace();
            }
            initWindow();
            initOther();
        }
        private void initOther(){
            jtp=new JTabbedPane(JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT);
        }
        private void initWindow(){
            start=new JButton("开始截取");
            cancel=new JButton("退出");
            start.addActionListener(this);
            cancel.addActionListener(this);
            JPanel buttonJP=new JPanel();
            c=new JPanel(new BorderLayout());
            JLabel jl=new JLabel("屏幕截取", JLabel.CENTER);
            jl.setFont(new Font("黑体",Font.BOLD,40));
            jl.setForeground(Color.RED);
            c.add(jl,BorderLayout.CENTER);
            buttonJP.add(start);
            buttonJP.add(cancel);
            buttonJP.setBorder(BorderFactory.createTitledBorder("公共操作区"));
            JPanel jp=new JPanel();//放置两个单选按钮的面板
            jp.add(java=new JRadioButton("java界面"));
            jp.add(system=new JRadioButton("系统界面",true));
            java.addActionListener(this);
            system.addActionListener(this);
            jp.setBorder(BorderFactory.createTitledBorder("界面风格"));
            ButtonGroup bg=new ButtonGroup();
            bg.add(java);
            bg.add(system);
            JPanel all=new JPanel();
            all.add(jp);
            all.add(buttonJP);
            this.getContentPane().add(c,BorderLayout.CENTER);
            this.getContentPane().add(all,BorderLayout.SOUTH);
            this.setSize(500,400);
            this.setLocationRelativeTo(null);
            this.setVisible(true);
            this.setAlwaysOnTop(true);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        
        private void updates(){
            this.setVisible(true);
            if(get!=null){
                //如果索引是0,则表示一张图片都没有被加入过,
                //则要清除当前的东西,重新把tabpane放进来
                if(index==0){
                    c.removeAll();
                    c.add(jtp,BorderLayout.CENTER);
                }else{//否则的话,直接对tabpane添加面板就可以了
                    //就什么都不用做了
                }
                PicPanel pic=new PicPanel(get);
                jtp.addTab("图片"+(++index),pic);
                jtp.setSelectedComponent(pic);
                SwingUtilities.updateComponentTreeUI(c); // 调整LookAndFeel(javax.swing)
            }
        }
        
        private void doStart(){
            try{
                this.setVisible(false);
                Thread.sleep(500);//睡500毫秒是为了让主窗完全不见
                Robot ro=new Robot(); // (通过本地操作)控制鼠标、键盘等实际输入源(java.awt)
                Toolkit tk=Toolkit.getDefaultToolkit(); // AWT组件的抽象父类(java.awt)
                Dimension di=tk.getScreenSize();
                Rectangle rec=new Rectangle(0,0,di.width,di.height);
                BufferedImage bi=ro.createScreenCapture(rec);
                JFrame jf=new JFrame();
                Temp temp=new Temp(jf,bi,di.width,di.height); // 自定义的Temp类的对象
                jf.getContentPane().add(temp,BorderLayout.CENTER);
                jf.setUndecorated(true);
                jf.setSize(di);
                jf.setVisible(true);
                jf.setAlwaysOnTop(true);
            } catch(Exception exe){
                exe.printStackTrace();
            }
        }
        
        /**
        *公用的处理保存图片的方法
        */
        public  void doSave(BufferedImage get){
            try{
                if(get==null){
                    JOptionPane.showMessageDialog(this
                      , "图片不能为空!!", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                JFileChooser jfc=new JFileChooser(".");
                jfc.addChoosableFileFilter(new GIFfilter());
                jfc.addChoosableFileFilter(new BMPfilter());
                jfc.addChoosableFileFilter(new JPGfilter());
                jfc.addChoosableFileFilter(new PNGfilter());
                int i=jfc.showSaveDialog(this);
                if(i==JFileChooser.APPROVE_OPTION){
                    File file=jfc.getSelectedFile();
                    String about="PNG";
                    String ext=file.toString().toLowerCase();
                    javax.swing.filechooser.FileFilter ff=jfc.getFileFilter();
                    if(ff instanceof JPGfilter){
                        if(!ext.endsWith(".jpg")){
                            String ns=ext+".jpg";
                            file=new File(ns);
                            about="JPG";
                        }
                    } else if(ff instanceof PNGfilter){
                        if(!ext.endsWith(".png")){
                            String ns=ext+".png";
                            file=new File(ns);
                            about="PNG";
                        }
                    }else if(ff instanceof BMPfilter){
                        if(!ext.endsWith(".bmp")){
                            String ns=ext+".bmp";
                            file=new File(ns);
                            about="BMP";
                        }
                    }else if(ff instanceof GIFfilter){
                        if(!ext.endsWith(".gif")){
                            String ns=ext+".gif";
                            file=new File(ns);
                            about="GIF";
                        }
                    }
                    if(ImageIO.write(get,about,file)){
                        JOptionPane.showMessageDialog(this,"保存成功!");
                    } else
                        JOptionPane.showMessageDialog(this,"保存失败!");
                }
            } catch(Exception exe){
                exe.printStackTrace();
            }
        }
        
        /** 
         *公共的处理把当前的图片加入剪帖板的方法
         */
        public void doCopy(final BufferedImage image){
            try{
                if(get==null){
                    JOptionPane.showMessageDialog(this
                      ,"图片不能为空!!","错误",JOptionPane.ERROR_MESSAGE);
                    return;
                } // java.awt.datatransfer(接口)
                Transferable trans = new Transferable(){ // 内部类
                    public DataFlavor[] getTransferDataFlavors() {
                        return new DataFlavor[] { DataFlavor.imageFlavor };
                    }
                    public boolean isDataFlavorSupported(DataFlavor flavor) {
                        return DataFlavor.imageFlavor.equals(flavor);
                    }
                    public Object getTransferData(DataFlavor flavor)
                      throws UnsupportedFlavorException, IOException {
                        if(isDataFlavorSupported(flavor))
                            return image;
                        throw new UnsupportedFlavorException(flavor);
                    }
                };
                
                Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
                JOptionPane.showMessageDialog(this,"已复制到系统粘帖板!!");
            }catch(Exception exe){
                exe.printStackTrace();
                JOptionPane.showMessageDialog(this
                  ,"复制到系统粘帖板出错!!","错误",JOptionPane.ERROR_MESSAGE);
            }
        }
        
        //处理关闭事件
        private void doClose(Component c){
            jtp.remove(c);
            c=null;
            System.gc();
        }
        
        public void actionPerformed(ActionEvent ae){
            Object source=ae.getSource();
            if(source==start){
                doStart();
            } else if(source==cancel){
                System.exit(0);
            }else if(source==java){ // 金属外观
                try{
                    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                    SwingUtilities.updateComponentTreeUI(this);
                }catch(Exception exe){
                    exe.printStackTrace();
                }
            }else if(source==system){ // 本地外观
                try{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    SwingUtilities.updateComponentTreeUI(this);
                }catch(Exception exe){
                    exe.printStackTrace();
                }
            }
        }
        
        //一个内部类,它表示一个面板,一个可以被放进tabpane的面板
        //也有自己的一套处理保存和复制的方法
        private class PicPanel extends JPanel implements ActionListener{
            JButton save,copy,close;//表示保存,复制,关闭的按钮
            BufferedImage get;//得到的图片
            public PicPanel(BufferedImage get){
                super(new BorderLayout());
                this.get=get;
                initPanel();
            }
            private void initPanel(){
                save=new JButton("保存(S)");
                copy=new JButton("复制到剪帖板(C)");
                close=new JButton("关闭(X)");
                save.setMnemonic('S');
                copy.setMnemonic('C');
                close.setMnemonic('X');
                JPanel buttonPanel=new JPanel();
                buttonPanel.add(copy);
                buttonPanel.add(save);
                buttonPanel.add(close);
                JLabel icon=new JLabel(new ImageIcon(get));
                this.add(new JScrollPane(icon),BorderLayout.CENTER);
                this.add(buttonPanel,BorderLayout.SOUTH);
                save.addActionListener(this);
                copy.addActionListener(this);
                close.addActionListener(this);
            }
            public void actionPerformed(ActionEvent e) {
                Object source=e.getSource();
                if(source==save){
                    doSave(get);
                }else if(source==copy){
                    doCopy(get);
                }else if(source==close){
                    get=null;
                    doClose(this);
                }
            }
        }
        
        //保存BMP格式的过滤器
        private class BMPfilter extends javax.swing.filechooser.FileFilter{
            public BMPfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".bmp")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.BMP(BMP图像)";
            }
        }
        
        //保存JPG格式的过滤器
        private class JPGfilter extends javax.swing.filechooser.FileFilter{
            public JPGfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".jpg")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.JPG(JPG图像)";
            }
        }
        
        //保存GIF格式的过滤器
        private class GIFfilter extends javax.swing.filechooser.FileFilter{
            public GIFfilter(){
            }
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".gif")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.GIF(GIF图像)";
            }
        }
        
        //保存PNG格式的过滤器
        private class PNGfilter extends javax.swing.filechooser.FileFilter{
            public boolean accept(File file){
                if(file.toString().toLowerCase().endsWith(".png")||
                        file.isDirectory()){
                    return true;
                } else
                    return false;
            }
            public String getDescription(){
                return "*.PNG(PNG图像)";
            }
        }
        
        //一个临时类,用于显示当前的屏幕图像
        private class Temp extends JPanel implements MouseListener,MouseMotionListener{
            private BufferedImage bi;
            private int width,height;
            private int startX,startY,endX,endY,tempX,tempY;
            private JFrame jf;
            private Rectangle select=new Rectangle(0,0,0,0);//表示选中的区域
            private Cursor cs=new Cursor(Cursor.CROSSHAIR_CURSOR);//表示一般情况下的鼠标状态(十字线)
            private States current=States.DEFAULT;// 表示当前的编辑状态
            private Rectangle[] rec;//表示八个编辑点的区域
            //下面四个常量,分别表示谁是被选中的那条线上的端点
            public static final int START_X=1;
            public static final int START_Y=2;
            public static final int END_X=3;
            public static final int END_Y=4;
            private int currentX,currentY;//当前被选中的X和Y,只有这两个需要改变
            private Point p=new Point();//当前鼠标移的地点
            private boolean showTip=true;//是否显示提示.如果鼠标左键一按,则提示就不再显示了
            
            public Temp(JFrame jf,BufferedImage bi,int width,int height){
                this.jf=jf;
                this.bi=bi;
                this.width=width;
                this.height=height;
                this.addMouseListener(this);
                this.addMouseMotionListener(this);
                initRecs();
            }
            
            private void initRecs(){
                rec=new Rectangle[8];
                for(int i=0;iendX?startX:endX)-5,y-5,10,10);
                rec[3]=new Rectangle((startX>endX?startX:endX)-5,y1-5,10,10);
                rec[4]=new Rectangle((startX>endX?startX:endX)-5,(startY>endY?startY:endY)-5,10,10);
                rec[5]=new Rectangle(x1-5,(startY>endY?startY:endY)-5,10,10);
                rec[6]=new Rectangle(x-5,(startY>endY?startY:endY)-5,10,10);
                rec[7]=new Rectangle(x-5,y1-5,10,10);
                if(showTip){
                    g.setColor(Color.CYAN);
                    g.fillRect(p.x,p.y,170,20);
                    g.setColor(Color.RED);
                    g.drawRect(p.x,p.y,170,20);
                    g.setColor(Color.BLACK);
                    g.drawString("请按住鼠标左键不放选择截图区",p.x,p.y+15);
                }
            }
            
            //根据东南西北等八个方向决定选中的要修改的X和Y的座标
            private void initSelect(States state){
                switch(state){
                    case DEFAULT:
                        currentX=0;
                        currentY=0;
                        break;
                    case EAST:
                        currentX=(endX>startX?END_X:START_X);
                        currentY=0;
                        break;
                    case WEST:
                        currentX=(endX>startX?START_X:END_X);
                        currentY=0;
                        break;
                    case NORTH:
                        currentX=0;
                        currentY=(startY>endY?END_Y:START_Y);
                        break;
                    case SOUTH:
                        currentX=0;
                        currentY=(startY>endY?START_Y:END_Y);
                        break;
                    case NORTH_EAST:
                        currentY=(startY>endY?END_Y:START_Y);
                        currentX=(endX>startX?END_X:START_X);
                        break;
                    case NORTH_WEST:
                        currentY=(startY>endY?END_Y:START_Y);
                        currentX=(endX>startX?START_X:END_X);
                        break;
                    case SOUTH_EAST:
                        currentY=(startY>endY?START_Y:END_Y);
                        currentX=(endX>startX?END_X:START_X);
                        break;
                    case SOUTH_WEST:
                        currentY=(startY>endY?START_Y:END_Y);
                        currentX=(endX>startX?START_X:END_X);
                        break;
                    default:
                        currentX=0;
                        currentY=0;
                        break;
                }
            }
            
            public void mouseMoved(MouseEvent me){
                doMouseMoved(me);
                initSelect(current); // current:当前状态(state)
                if(showTip){
                    p=me.getPoint();
                    repaint();
                }
            }
            
            //特意定义一个方法处理鼠标移动,是为了每次都能初始化一下所要选择的区域
            private void doMouseMoved(MouseEvent me){
                if(select.contains(me.getPoint())){
                    this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
                    current=States.MOVE;
                } else{
                    States[] st=States.values();
                    for(int i=0;i=this.getWidth()){
                                wid=this.getWidth()-select.x;
                            }
                            if(select.y+select.height>=this.getHeight()){
                                het=this.getHeight()-select.y;
                            }
                            get=bi.getSubimage(select.x,select.y,wid,het);
                            jf.dispose();
                            updates();
                        }
                    }
                }
            }
        }
        
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    new CaptureScreen();
                }
            });
        }
    }
    
    //一些表示状态的枚举
    enum States{
        NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)),//表示西北角
        NORTH(new Cursor(Cursor.N_RESIZE_CURSOR)),
        NORTH_EAST(new Cursor(Cursor.NE_RESIZE_CURSOR)),
        EAST(new Cursor(Cursor.E_RESIZE_CURSOR)),
        SOUTH_EAST(new Cursor(Cursor.SE_RESIZE_CURSOR)),
        SOUTH(new Cursor(Cursor.S_RESIZE_CURSOR)),
        SOUTH_WEST(new Cursor(Cursor.SW_RESIZE_CURSOR)),
        WEST(new Cursor(Cursor.W_RESIZE_CURSOR)),
        MOVE(new Cursor(Cursor.MOVE_CURSOR)),
        DEFAULT(new Cursor(Cursor.DEFAULT_CURSOR));
        
        private Cursor cs;
        
        States(Cursor cs){
            this.cs=cs;
        }
        
        public Cursor getCursor(){
            return cs;
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。