1

我正在制作一个屏幕截图程序,所以当您按下屏幕截图按钮时,会弹出一个 JMessageDial 并提示您使用您的图像,它会告诉您拖动鼠标并在您想要截取屏幕截图的区域周围制作一个框。当用户单击确定时,我似乎无法找到如何在框内获取图像。

所以我需要帮助的是获取用户用鼠标“绘制”的矩形内的图像,并将其存储在一个变量中。

下面是具体代码:

public void selectArea(final BufferedImage screen) throws Exception {
    final BufferedImage screenCopy = new BufferedImage(screen.getWidth(), screen.getHeight(), screen.getType());
    final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy));
    JScrollPane screenScroll = new JScrollPane(screenLabel);

    screenScroll.setPreferredSize(new Dimension((int)(screen.getWidth()/2), (int)(screen.getHeight()/2)));

    JPanel panel = new JPanel(new BorderLayout());
    panel.add(screenScroll, BorderLayout.CENTER);

    final JLabel selectionLabel = new JLabel("Draw a rectangle");
    panel.add(selectionLabel, BorderLayout.SOUTH);
    repaint(screen, screenCopy);
    screenLabel.repaint();

    screenLabel.addMouseMotionListener(new MouseMotionAdapter() {

        @Override
        public void mouseMoved(MouseEvent me) {
            start = me.getPoint();
            repaint(screen, screenCopy);
            selectionLabel.setText("Start Point: " + start);
            screenLabel.repaint();
        }

        @Override
        public void mouseDragged(MouseEvent me) {
            end = me.getPoint();
            captureRect = new Rectangle(start, new Dimension(end.x-start.x, end.y-start.y));
            try {
                paintFinalImage(new BufferedImage((int)screenCopy.getGraphics().getClipBounds(captureRect).getWidth()+1,
                        (int)screenCopy.getGraphics().getClipBounds(captureRect).getHeight()+1, screen.getType()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            repaint(screen, screenCopy);
            screenLabel.repaint();
            selectionLabel.setText("Rectangle: " + captureRect);
        }
    });
    JOptionPane.showMessageDialog(null, panel, "Select your image", JOptionPane.OK_OPTION, new ImageIcon(""));
    uploadImage(screenShot);
    System.out.println("Final rectangle: " + screenCopy.getGraphics().getClipBounds(captureRect));
}

如果您需要,这是完整的课程:

package com.screencapture;


import java.awt.*;

public class Main implements ActionListener, ItemListener, KeyListener, NativeKeyListener {

    private final Image icon = Toolkit.getDefaultToolkit().getImage("./data/icon.gif");
    private final TrayIcon trayIcon = new TrayIcon(icon, "Screen Snapper");
    private JFrame frame;
    private Rectangle captureRect;
    private JComboBox<String> imageType;
    private boolean hideWhenMinimized = false;
    private final String API_KEY = "b84e430b4a65d16a6955358141f21a61";
    private static Robot robot;
    private BufferedImage screenShot;
    private Point end;
    private Point start;

    public static void main(String[] args) throws Exception {
        robot = new Robot();
        new Main().start();
    }

    public void start() throws Exception {
        GlobalScreen.getInstance().registerNativeHook();
        GlobalScreen.getInstance().addNativeKeyListener(this);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        frame = new JFrame("White power!");
        frame.setPreferredSize(new Dimension(250, 250));
        frame.getContentPane().setLayout(null);
        frame.setIconImage(icon);
        frame.addKeyListener(this);
        frame.addWindowListener(new WindowListener() {

            @Override
            public void windowOpened(WindowEvent e) {}

            @Override
            public void windowClosing(WindowEvent e) {}

            @Override
            public void windowClosed(WindowEvent e) {}

            @Override
            public void windowIconified(WindowEvent e) {
                if (hideWhenMinimized)
                    frame.setVisible(false);
            }

            @Override
            public void windowDeiconified(WindowEvent e) {}

            @Override
            public void windowActivated(WindowEvent e) {}

            @Override
            public void windowDeactivated(WindowEvent e)  {}

        });

        JLabel lblImageType = new JLabel("Image Format:");
        lblImageType.setBounds(10, 11, 90, 14);
        frame.getContentPane().add(lblImageType);

        String[] imageTypes = {"PNG", "JPG"};
        imageType = new JComboBox<String>(imageTypes);
        imageType.setBounds(106, 8, 51, 20);
        frame.getContentPane().add(imageType);

        JButton btnTakeScreenShot = new JButton("ScreenShot");
        btnTakeScreenShot.setBounds(24, 69, 115, 23);
        frame.getContentPane().add(btnTakeScreenShot);
        btnTakeScreenShot.addActionListener(this);

        setTrayIcon();
        frame.pack();
        frame.setVisible(true);
    }

    public void setTrayIcon() throws AWTException {
        CheckboxMenuItem startup = new CheckboxMenuItem("Run on start-up");
        CheckboxMenuItem hide = new CheckboxMenuItem("Hide when minimized");
        String[] popupMenuOptions = {"Open", "Exit"};
        if (SystemTray.isSupported()) {
            SystemTray tray = SystemTray.getSystemTray();
            trayIcon.setImageAutoSize(true);
            PopupMenu popupMenu = new PopupMenu();
            for (String option : popupMenuOptions) {
                if (option == "Exit") {
                    popupMenu.add(startup);
                    popupMenu.add(hide);
                    popupMenu.add(option);
                } else {
                    popupMenu.add(option);
                }
            }
            trayIcon.setPopupMenu(popupMenu);
            popupMenu.addActionListener(this);
            startup.addItemListener(this);
            hide.addItemListener(this);
            trayIcon.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    frame.setVisible(true);
                }

            });
            tray.add(trayIcon);
        }
    }

    public void selectArea(final BufferedImage screen) throws Exception {
        final BufferedImage screenCopy = new BufferedImage(screen.getWidth(), screen.getHeight(), screen.getType());
        final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy));
        JScrollPane screenScroll = new JScrollPane(screenLabel);

        screenScroll.setPreferredSize(new Dimension((int)(screen.getWidth()/2), (int)(screen.getHeight()/2)));

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(screenScroll, BorderLayout.CENTER);

        final JLabel selectionLabel = new JLabel("Draw a rectangle");
        panel.add(selectionLabel, BorderLayout.SOUTH);
        repaint(screen, screenCopy);
        screenLabel.repaint();

        screenLabel.addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseMoved(MouseEvent me) {
                start = me.getPoint();
                repaint(screen, screenCopy);
                selectionLabel.setText("Start Point: " + start);
                screenLabel.repaint();
            }

            @Override
            public void mouseDragged(MouseEvent me) {
                end = me.getPoint();
                captureRect = new Rectangle(start, new Dimension(end.x-start.x, end.y-start.y));
                try {
                    paintFinalImage(new BufferedImage((int)screenCopy.getGraphics().getClipBounds(captureRect).getWidth()+1,
                            (int)screenCopy.getGraphics().getClipBounds(captureRect).getHeight()+1, screen.getType()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                repaint(screen, screenCopy);
                screenLabel.repaint();
                selectionLabel.setText("Rectangle: " + captureRect);
            }
        });
        JOptionPane.showMessageDialog(null, panel, "Select your image", JOptionPane.OK_OPTION, new ImageIcon(""));
        uploadImage(screenShot);
        System.out.println("Final rectangle: " + screenCopy.getGraphics().getClipBounds(captureRect));
    }

    public void paintFinalImage(BufferedImage image) throws Exception {
        screenShot = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
        Graphics2D g = screenShot.createGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();
    }

    public void repaint(BufferedImage orig, BufferedImage copy) {
        Graphics2D g = copy.createGraphics();
        g.drawImage(orig, 0, 0, null);
        if (captureRect != null) {
            g.setColor(Color.BLACK);
            g.draw(captureRect);
        }
        g.dispose();
    }

    public void uploadImage(BufferedImage image) throws Exception {
        String IMGUR_POST_URI = "http://api.imgur.com/2/upload.xml";
        String IMGUR_API_KEY = API_KEY;
        String readLine = null;
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, imageType.getSelectedItem().toString(), outputStream);
            URL url = new URL(IMGUR_POST_URI);

            String data = URLEncoder.encode("image", "UTF-8") + "=" + URLEncoder.encode(Base64.encodeBase64String(outputStream.toByteArray()).toString(), "UTF-8");
            data += "&" + URLEncoder.encode("key", "UTF-8") + "=" + URLEncoder.encode(IMGUR_API_KEY, "UTF-8");

            URLConnection urlConnection = url.openConnection();
            urlConnection.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
            wr.write(data);
            wr.flush();
            InputStream inputStream;
            if (((HttpURLConnection) urlConnection).getResponseCode() == 400) {
                inputStream = ((HttpURLConnection) urlConnection).getErrorStream();
            } else {
                inputStream = urlConnection.getInputStream();
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while ((line = reader.readLine()) != null) {
                readLine = line;
            }
            wr.close();
            reader.close();
        } catch(Exception e){
            e.printStackTrace();
        }
        String URL = readLine.substring(readLine.indexOf("<original>") + 10, readLine.indexOf("</original>"));
        System.out.println(URL);
        Toolkit.getDefaultToolkit().beep();
        StringSelection stringSelection = new StringSelection(URL);
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        System.out.println(command);
        if (command.equalsIgnoreCase("open")) {
            frame.setVisible(true);
        } else if (command.equalsIgnoreCase("exit")) {
            System.exit(-1);
        } else if (command.equalsIgnoreCase("screenshot")) {
            try {
                final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
                selectArea(screen);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        System.out.println(e.getItem() + ", " +e.getStateChange());
        String itemChanged = e.getItem().toString();
        if (itemChanged.equalsIgnoreCase("run on start-up")) {
            //TODO
        } else if (itemChanged.equalsIgnoreCase("hide when minimized")) {
            if (e.getStateChange() == ItemEvent.DESELECTED) {
                hideWhenMinimized = false;
            } else if (e.getStateChange() == ItemEvent.SELECTED) {
                hideWhenMinimized = true;
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
        System.out.println("KeyTyped: "+e.getKeyCode());
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent e) {
        System.out.println("KeyReleased: "+e.getKeyCode());
        System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
        if (e.getKeyCode() == 154) {
            try {
                final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
                selectArea(screen);
                frame.setVisible(true);
            } catch(Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent e) {
    }
}
4

1 回答 1

2

我建议你简化你的问题来解决它。创建一个小的可编译和可运行程序,它没有当前代码的所有包袱,但其唯一目标是显示图像,并让用户选择该图像的子部分。然后,如果您的尝试失败,您可以在此处发布您的尝试,我们实际上可以运行它并理解它,并希望能够修复它。

例如,这里有一小段可编译和可运行的代码,它使用 MouseListener 来选择图像的一小部分。也许你可以从中得到一些想法:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class ImagePlay extends JPanel {
   public static final String IMAGE_PATH = "http://upload.wikimedia.org/wikipedia/" +
        "commons/thumb/3/39/European_Common_Frog_Rana_temporaria.jpg/" +
        "800px-European_Common_Frog_Rana_temporaria.jpg";
   private static final Color RECT_COLOR = new Color(180, 180, 255);
   private BufferedImage img = null;
   Point p1 = null;
   Point p2 = null;

   public ImagePlay() {
      URL imgUrl;
      try {
         imgUrl = new URL(IMAGE_PATH);
         img = ImageIO.read(imgUrl );
         ImageIcon icon = new ImageIcon(img);
         JLabel label = new JLabel(icon) {
            @Override
            protected void paintComponent(Graphics g) {
               super.paintComponent(g);
               myLabelPaint(g);
            }
         };

         setLayout(new BorderLayout());
         add(new JScrollPane(label));

         MouseAdapter mAdapter = new MyMouseAdapter();
         label.addMouseListener(mAdapter);
         label.addMouseMotionListener(mAdapter);

      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   private void myLabelPaint(Graphics g) {
      if (p1 != null && p2 != null) {
         int x = Math.min(p1.x, p2.x);
         int y = Math.min(p1.y, p2.y);
         int width = Math.abs(p1.x - p2.x);
         int height = Math.abs(p1.y - p2.y);
         g.setXORMode(Color.DARK_GRAY);
         g.setColor(RECT_COLOR);
         g.drawRect(x, y, width, height);
      }
   }

   private class MyMouseAdapter extends MouseAdapter {

      @Override
      public void mousePressed(MouseEvent e) {
         p1 = e.getPoint();
         p2 = null;
         repaint();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         p2 = e.getPoint();
         repaint();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         p2 = e.getPoint();
         repaint();

         int x = Math.min(p1.x, p2.x);
         int y = Math.min(p1.y, p2.y);
         int width = Math.abs(p1.x - p2.x);
         int height = Math.abs(p1.y - p2.y);
         BufferedImage smlImg = img.getSubimage(x, y, width, height);
         ImageIcon icon = new ImageIcon(smlImg);
         JLabel label = new JLabel(icon);
         JOptionPane.showMessageDialog(ImagePlay.this, label, "Selected Image", 
               JOptionPane.PLAIN_MESSAGE);         
      }
   }


   private static void createAndShowGui() {
      ImagePlay mainPanel = new ImagePlay();

      JFrame frame = new JFrame("ImagePlay");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

它使用在线获取的公开可用图像,添加到 JLabel 的 MouseListener,并且 JLabel 的paintComponent(...)方法被覆盖,以便显示来自 MouseListener/Adapter 的指南。它通过 BufferedImage 的方法创建子图像getSubimage(...),然后将其显示在 JOptionPane 中,但如果需要保存图像将是微不足道的。

于 2012-06-20T02:21:09.390 回答