2012-06-20 3 views
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) { 
    } 
} 
+3

[Это много кода для чтения.] (Http://meta.stackexchange.com/a/129787/175248). У вас есть очень специфическая область - как получить изображения внутри прямоугольника - как вы думаете вы можете включить только код, который пытается это сделать? – Makoto

+0

Теперь я добавил конкретный метод. Извини за это. –

ответ

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(); 
     } 
     }); 
    } 
} 

Он использует общедоступное изображение, полученное в Интернете, а MouseListener, который добавляется к JLabel, и JLabel имеет свой метод paintComponent(...) переопределен таким образом, чтобы показать направляющие линии от MouseListener/адаптер. Он создает суб изображение с помощью метода BufferedImage getSubimage(...), а затем отображает его на JOptionPane, но было бы тривиально сохранять изображение, если это необходимо.

Смежные вопросы