Proste, jak głosi tytuł: Czy możesz używać tylko poleceń Java, aby zrobić zrzut ekranu i go zapisać? A może muszę użyć programu dla konkretnego systemu operacyjnego, aby zrobić zrzut ekranu, a następnie wyjąć go ze schowka?
java
image
screenshot
jjnguy
źródło
źródło
Odpowiedzi:
Wierz lub nie, ale możesz użyć
java.awt.Robot
do „stworzenia obrazu zawierającego piksele odczytane z ekranu”. Następnie możesz zapisać ten obraz do pliku na dysku.Właśnie tego spróbowałem i wszystko kończy się tak:
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); BufferedImage capture = new Robot().createScreenCapture(screenRect); ImageIO.write(capture, "bmp", new File(args[0]));
UWAGA: Spowoduje to przechwycenie tylko monitora głównego. Zobacz GraphicsConfiguration, aby uzyskać obsługę wielu monitorów.
źródło
Nigdy nie lubiłem używać Robot, więc stworzyłem własną prostą metodę robienia zrzutów ekranu obiektów JFrame:
public static final void makeScreenshot(JFrame argFrame) { Rectangle rec = argFrame.getBounds(); BufferedImage bufferedImage = new BufferedImage(rec.width, rec.height, BufferedImage.TYPE_INT_ARGB); argFrame.paint(bufferedImage.getGraphics()); try { // Create temp file File temp = File.createTempFile("screenshot", ".png"); // Use the ImageIO API to write the bufferedImage to a temporary file ImageIO.write(bufferedImage, "png", temp); // Delete temp file when program exits temp.deleteOnExit(); } catch (IOException ioe) { ioe.printStackTrace(); } }
źródło
Robot
dostajesz tylko zawartość okna, podczas gdy możesz również pobrać ramkę okna i pasek tytułu.Jeśli chcesz przechwycić wszystkie monitory, możesz użyć następującego kodu:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] screens = ge.getScreenDevices(); Rectangle allScreenBounds = new Rectangle(); for (GraphicsDevice screen : screens) { Rectangle screenBounds = screen.getDefaultConfiguration().getBounds(); allScreenBounds.width += screenBounds.width; allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height); } Robot robot = new Robot(); BufferedImage screenShot = robot.createScreenCapture(allScreenBounds);
źródło
public void captureScreen(String fileName) throws Exception { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle screenRectangle = new Rectangle(screenSize); Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(screenRectangle); ImageIO.write(image, "png", new File(fileName)); }
źródło
import java.awt.Color; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.*; public class HelloWorldFrame extends JFrame implements ActionListener { JButton b; public HelloWorldFrame() { this.setVisible(true); this.setLayout(null); b = new JButton("Click Here"); b.setBounds(380, 290, 120, 60); b.setBackground(Color.red); b.setVisible(true); b.addActionListener(this); add(b); setSize(1000, 700); } public void actionPerformed(ActionEvent e) { if (e.getSource() == b) { this.dispose(); try { Thread.sleep(1000); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); Rectangle rec = new Rectangle(0, 0, d.width, d.height); Robot ro = new Robot(); BufferedImage img = ro.createScreenCapture(rec); File f = new File("myimage.jpg");//set appropriate path ImageIO.write(img, "jpg", f); } catch (Exception ex) { System.out.println(ex.getMessage()); } } } public static void main(String[] args) { HelloWorldFrame obj = new HelloWorldFrame(); } }
źródło
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] screens = ge.getScreenDevices(); Rectangle allScreenBounds = new Rectangle(); for (GraphicsDevice screen : screens) { Rectangle screenBounds = screen.getDefaultConfiguration().getBounds(); allScreenBounds.width += screenBounds.width; allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height); allScreenBounds.x=Math.min(allScreenBounds.x, screenBounds.x); allScreenBounds.y=Math.min(allScreenBounds.y, screenBounds.y); } Robot robot = new Robot(); BufferedImage bufferedImage = robot.createScreenCapture(allScreenBounds); File file = new File("C:\\Users\\Joe\\Desktop\\scr.png"); if(!file.exists()) file.createNewFile(); FileOutputStream fos = new FileOutputStream(file); ImageIO.write( bufferedImage, "png", fos );
bufferedImage będzie zawierał pełny zrzut ekranu, który został przetestowany na trzech monitorach
źródło
Możesz użyć
java.awt.Robot
do osiągnięcia tego zadania.poniżej znajduje się kod serwera, który zapisuje przechwycony zrzut ekranu jako obraz w Twoim katalogu.
import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.sql.SQLException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.imageio.ImageIO; public class ServerApp extends Thread { private ServerSocket serverSocket=null; private static Socket server = null; private Date date = null; private static final String DIR_NAME = "screenshots"; public ServerApp() throws IOException, ClassNotFoundException, Exception{ serverSocket = new ServerSocket(61000); serverSocket.setSoTimeout(180000); } public void run() { while(true) { try { server = serverSocket.accept(); date = new Date(); DateFormat dateFormat = new SimpleDateFormat("_yyMMdd_HHmmss"); String fileName = server.getInetAddress().getHostName().replace(".", "-"); System.out.println(fileName); BufferedImage img=ImageIO.read(ImageIO.createImageInputStream(server.getInputStream())); ImageIO.write(img, "png", new File("D:\\screenshots\\"+fileName+dateFormat.format(date)+".png")); System.out.println("Image received!!!!"); //lblimg.setIcon(img); } catch(SocketTimeoutException st) { System.out.println("Socket timed out!"+st.toString()); //createLogFile("[stocktimeoutexception]"+stExp.getMessage()); break; } catch(IOException e) { e.printStackTrace(); break; } catch(Exception ex) { System.out.println(ex); } } } public static void main(String [] args) throws IOException, SQLException, ClassNotFoundException, Exception{ ServerApp serverApp = new ServerApp(); serverApp.createDirectory(DIR_NAME); Thread thread = new Thread(serverApp); thread.start(); } private void createDirectory(String dirName) { File newDir = new File("D:\\"+dirName); if(!newDir.exists()){ boolean isCreated = newDir.mkdir(); } } }
A to jest kod klienta, który działa w wątku i po kilku minutach przechwytuje zrzut ekranu ekranu użytkownika.
package com.viremp.client; import java.awt.AWTException; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.Socket; import java.util.Random; import javax.imageio.ImageIO; public class ClientApp implements Runnable { private static long nextTime = 0; private static ClientApp clientApp = null; private String serverName = "192.168.100.18"; //loop back ip private int portNo = 61000; //private Socket serverSocket = null; /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { clientApp = new ClientApp(); clientApp.getNextFreq(); Thread thread = new Thread(clientApp); thread.start(); } private void getNextFreq() { long currentTime = System.currentTimeMillis(); Random random = new Random(); long value = random.nextInt(180000); //1800000 nextTime = currentTime + value; //return currentTime+value; } @Override public void run() { while(true){ if(nextTime < System.currentTimeMillis()){ System.out.println(" get screen shot "); try { clientApp.sendScreen(); clientApp.getNextFreq(); } catch (AWTException e) { // TODO Auto-generated catch block System.out.println(" err"+e); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch(Exception e){ e.printStackTrace(); } } //System.out.println(" statrted ...."); } } private void sendScreen()throws AWTException, IOException { Socket serverSocket = new Socket(serverName, portNo); Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dimensions = toolkit.getScreenSize(); Robot robot = new Robot(); // Robot class BufferedImage screenshot = robot.createScreenCapture(new Rectangle(dimensions)); ImageIO.write(screenshot,"png",serverSocket.getOutputStream()); serverSocket.close(); } }
źródło
Toolkit zwraca piksele na podstawie PPI, w wyniku czego zrzut ekranu nie jest tworzony dla całego ekranu, gdy PPI> 100% w systemie Windows. Proponuję to zrobić:
DisplayMode displayMode = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode(); Rectangle screenRectangle = new Rectangle(displayMode.getWidth(), displayMode.getHeight()); BufferedImage screenShot = new Robot().createScreenCapture(screenRectangle);
źródło