2014-10-15 3 views
0

Я ищу снимок экрана о том, что в настоящее время происходит в моей программе, для использования на фоне меню паузы. Я нашел код:Захват скриншота без рамки

BufferedImage x = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 

, который делает снимок экрана и работает хорошо, дело в том, что также включает в себя мои окна границы, которые, безусловно, не должны быть включены. Я следил за Интернетом, и я не видел функции, чтобы сделать снимок экрана ТОЛЬКО того, что находится внутри границы. Кроме того, поиск толщины границы сверху, снизу и сторон также будет работать, но я не нашел никакой информации об этом.

Каков наилучший способ сделать это?

ответ

2

Вместо захвата кадров границы, вы должны попытаться захватить содержимое вместо этого, например ...

JRootPane rootPane = frame.getRootPane(); 
Rectangle bounds = new Rectangle(rootPane.getSize()); 
bounds.setLocation(rootPane.getLocationOnScreen()); 
BufferedImage contentsImage = bot.createScreenCapture(bounds); 

Это будет захватить строку меню, а также, если вы хотите только физическое содержание, вы должны использовать frame.getContentPane() вместо frame.getRootPane()

К примеру ...

Оригинальная рамка
Original

результатов съемки (полный кадр/базовая панель)
Capture

import java.awt.AWTException; 
import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JRootPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ScreenShot { 

    public static void main(String[] args) { 
     new ScreenShot(); 
    } 

    public ScreenShot() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       final JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 

       JButton capture = new JButton("Snap shot"); 
       capture.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         try { 
          Robot bot = new Robot(); 
          BufferedImage frameImage = bot.createScreenCapture(frame.getBounds()); 
          JRootPane rootPane = frame.getRootPane(); 
          Rectangle bounds = new Rectangle(rootPane.getSize()); 
          bounds.setLocation(rootPane.getLocationOnScreen()); 
          BufferedImage contentsImage = bot.createScreenCapture(bounds); 

          JPanel panel = new JPanel(new GridLayout(1, 2)); 
          panel.add(new JLabel(new ImageIcon(frameImage))); 
          panel.add(new JLabel(new ImageIcon(contentsImage))); 

          JOptionPane.showMessageDialog(frame, panel); 

         } catch (AWTException ex) { 
          ex.printStackTrace(); 
         } 
        } 
       }); 

       frame.add(capture, BorderLayout.SOUTH); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 

      setLayout(new BorderLayout()); 

      try { 
       BufferedImage img = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\sillydash-small.png")); 
       JLabel label = new JLabel(new ImageIcon(img)); 
       add(label); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

     } 

    } 

} 

Как ни странно, вы можете использовать этот подход для любого компонента, который вы хотите ...

+0

Работал отлично! Я забыл об использовании rootPane для размеров и позиций, я знал, что должен быть какой-то объект, который содержит все и охватывает все между границами, просто не мог вспомнить, какой! Благодаря! – Nathan

+0

Рад, что это помогло ... – MadProgrammer

0

Вы можете попробовать сделать свою собственную функцию:

public static final void makeScreenshot(JFrame f) { 
    Rectangle rec = f.getBounds(); 
    BufferedImage bufferedImage = new BufferedImage(rec.width, rec.height, 
      BufferedImage.TYPE_INT_ARGB); 
    f.paint(bufferedImage.getGraphics()); 

    try { 
     // Create temp file 
     File temp = File.createTempFile("screenshot", ".png"); 

     ImageIO.write(bufferedImage, "png", temp); 

     // Delete temp file on exit 
     temp.deleteOnExit(); 
    } catch (IOException ioe) { 
     LOGGER.debug(ioe.toString()); 
    } 
} 

Это не включает в себя саму рамку или заголовок окна, поэтому он должен соответствовать вашим потребностям.

Редактировать Отредактировано для включения сохранения снимка.

+0

'JFrame # getBounds' действительно включает рамку доска, он представляет внешний край окна, все остальное отображается внутри него ... В зависимости от внешнего вида и других параметров зависит от того, что будет делать 'paint', но вы должны использовать' print' или 'printAll 'over' paint', поскольку он более эффективен и отключает двойную буферизацию – MadProgrammer

+0

О, видимо, 'paint' не нарисовывает границу, там вы идете, но я бы предложил другие исправления wou ld быть полезным (т.е. 'print' вместо' paint');) – MadProgrammer

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