Java(Swing)代码实现选择截屏

最近工作上需要,做了一个截图功能,同时分享出来。

其中又两种方式截图:

1,自定义截图,任意选取区域进行截图;

2,指定位置和大小直接截图,不可更改。

代码如下:

ScreenShotWindow类(截图窗口)
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ScreenShotWindow extends JWindow{
    private int orgx, orgy, endx, endy;
    private BufferedImage image=null;
    private BufferedImage tempImage=null;
    private BufferedImage saveImage=null;

    private ToolsWindow tools=null;

    private String type;

    /**
     * 自定义截图,可以选取区域
     */
    public ScreenShotWindow(){
        try{
            //获取屏幕尺寸
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
            this.setBounds(0, 0, d.width, d.height);

            //截取屏幕
            Robot robot = new Robot();
            image = robot.createScreenCapture(new Rectangle(0, 0, d.width,d.height));

            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    //鼠标松开时记录结束点坐标,并隐藏操作窗口
                    orgx = e.getX();
                    orgy = e.getY();

                    if(tools!=null){
                        tools.setVisible(false);
                    }
                }
                @Override
                public void mouseReleased(MouseEvent e) {
                    //鼠标松开时,显示操作窗口
                    if(tools==null){
                        tools=new ToolsWindow(ScreenShotWindow.this,e.getX(),e.getY());
                    }else{
                        tools.setLocation(e.getX(),e.getY());
                    }
                    tools.setVisible(true);
                    tools.toFront();
                }
            });

            this.addMouseMotionListener(new MouseMotionAdapter() {

                @Override
                public void mouseDragged(MouseEvent e) {
                    //鼠标拖动时,记录坐标并重绘窗口
                    endx = e.getX();
                    endy = e.getY();

                    //临时图像,用于缓冲屏幕区域放置屏幕闪烁
                    Image tempImage2=createImage(ScreenShotWindow.this.getWidth(), ScreenShotWindow.this.getHeight());
                    Graphics g =tempImage2.getGraphics();
                    g.drawImage(tempImage, 0, 0, null);
                    int x = Math.min(orgx, endx);
                    int y = Math.min(orgy, endy);
                    int width = Math.abs(endx - orgx)+1;
                    int height = Math.abs(endy - orgy)+1;
                    // 加上1防止width或height0
                    g.setColor(Color.BLUE);
                    g.drawRect(x-1, y-1, width+1, height+1);
                    //减1加1都了防止图片矩形框覆盖掉
                    saveImage = image.getSubimage(x, y, width, height);
                    g.drawImage(saveImage, x, y, null);

                    ScreenShotWindow.this.getGraphics().drawImage(tempImage2,0,0, ScreenShotWindow.this);
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 指定区域截图,其中X,Y,WIDTH,HEIGHT可以传入,需要事可以修改构造器,注意,不需要再次setVisible(true);
     * @param _type
     */
    public ScreenShotWindow(String _type){
        type = _type;
        try{
            //获取屏幕尺寸
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
            this.setBounds(0, 0, d.width, d.height);
            this.setVisible(true);
            //截取屏幕
            Robot robot = new Robot();
            image = robot.createScreenCapture(new Rectangle(0, 0, d.width,d.height));

            RescaleOp ro = new RescaleOp(0.8f, 0, null);
            tempImage = ro.filter(image, null);
            this.getGraphics().drawImage(tempImage, 0, 0, this);


            //临时图像,用于缓冲屏幕区域放置屏幕闪烁
            Image tempImage2=createImage(ScreenShotWindow.this.getWidth(), ScreenShotWindow.this.getHeight());
            Graphics g =tempImage2.getGraphics();
            g.drawImage(tempImage, 0, 0, null);
            int x = 100;
            int y = 100;
            int width = 100;
            int height = 100;
            // 加上1防止width或height0
            g.setColor(Color.BLUE);
            g.drawRect(x-1, y-1, width+1, height+1);
            //减1加1都了防止图片矩形框覆盖掉
            saveImage = image.getSubimage(x, y, width, height);
            g.drawImage(saveImage, x, y, null);

            this.getGraphics().drawImage(tempImage2,0,0, this);


            tools=new ToolsWindow(this,x+width,y+height);
            tools.setVisible(true);
            tools.toFront();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    @Override
    public void paint(Graphics g) {
        if(type!=null && type != ""){
            return;
        }
        RescaleOp ro = new RescaleOp(0.8f, 0, null);
        tempImage = ro.filter(image, null);
        g.drawImage(tempImage, 0, 0, this);
    }
    //保存图像到文件
    public void saveImage() throws IOException {
        JFileChooser jfc=new JFileChooser();
        jfc.setDialogTitle("保存");

        //文件过滤器,用户过滤可选择文件
        FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG", "jpg");//过滤文件名,只显示jpg格式文件
        jfc.setFileFilter(filter);  //将文件过滤器加入到文件选择中

        //初始化一个默认文件(此文件会生成到桌面上)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyymmddHHmmss");
        String fileName = sdf.format(new Date());  //把时间作为图片名(防止图片名重复,而把之前的图片覆盖)
        File filePath = FileSystemView.getFileSystemView().getHomeDirectory();  //获取系统桌面的路径
        File defaultFile = new File(filePath + File.separator + fileName + ".jpg");
        jfc.setSelectedFile(defaultFile);

        int flag = jfc.showSaveDialog(this);
        if(flag==JFileChooser.APPROVE_OPTION){
            File file=jfc.getSelectedFile();
            String path=file.getPath();
            //检查文件后缀,放置用户忘记输入后缀或者输入不正确的后缀
            if(!(path.endsWith(".jpg")||path.endsWith(".JPG"))){
                path+=".jpg";
            }
            //写入文件
            ImageIO.write(saveImage,"jpg",new File(path));
            System.exit(0);
        }
    }
}
ToolsWindow类(操作窗口)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

public class ToolsWindow extends JWindow{
    private ScreenShotWindow parent;

    public ToolsWindow(ScreenShotWindow parent, int x, int y) {
        this.parent=parent;
        this.init();
        this.setLocation(x, y);
        this.pack();
        this.setVisible(true);
    }

    private void init(){

        this.setLayout(new BorderLayout());
        JToolBar toolBar=new JToolBar("Java 截图");

        //保存按钮
        JButton saveButton=new JButton("save");
        saveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parent.saveImage();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });
        toolBar.add(saveButton);

        //关闭按钮
        JButton closeButton=new JButton("cancel");
        closeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        toolBar.add(closeButton);

        this.add(toolBar,BorderLayout.NORTH);
    }

}
Test类
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        try {
            //自定义区域截图
            ScreenShotWindow ssw=new ScreenShotWindow();
            ssw.setVisible(true);
            //指定区域截图
//            ScreenShotWindow ssw=new ScreenShotWindow("123");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

效果还不错,不过需要注意的是,点击保存后选择图片保存位置时,如果选择取消,会有bug,自行修改吧,很简单的,我懒得改了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值