Java kullanarak ekran görüntüsü almanın ve bir tür görüntüye kaydetmenin bir yolu var mı?


128

Başlığın belirttiği gibi basit: Ekran görüntüsü alıp kaydetmek için yalnızca Java komutlarını kullanabilir misiniz? Veya ekran görüntüsünü alıp panodan kapmak için işletim sistemine özel bir program kullanmam gerekir mi?



Bu kadar basit olacağını hiç bilmiyordum.
jjnguy

2
Bu soru sayesinde, bloguma yeni başlayanlar için bir öğretici yazdım: thepcwizard.in/2012/12/java-screen-capturing-tutorial.html
ThePCWizard

Yanıtlar:


187

İster inanın ister inanmayın, aslında java.awt.Robot"ekrandan okunan pikselleri içeren bir görüntü oluşturmak" için kullanabilirsiniz . Daha sonra bu görüntüyü diskteki bir dosyaya yazabilirsiniz.

Sadece denedim ve her şey şu şekilde sonuçlandı:

Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "bmp", new File(args[0]));

NOT: Bu yalnızca birincil monitörü yakalayacaktır. Çoklu monitör desteği için Grafik Yapılandırması'na bakın .


1
Elluminate ( elluminate.com ) gibi ekran paylaşım uygulamalarının kullandığı şeyin bu olup olmadığını merak ediyorum .
Chris Wagner

@java_enthu aslında evet, uygulamanızda ekran görüntüsüne giden yolu sabit bir şekilde kodlarsanız konsol olmadan çalışacaktır.
Dmitry Zagorulkin

2
Robot, ekran görüntüsüne fareyi dahil etmez. Aynı şeyi yapan benzer bir işlev var mı, ancak fareyi İÇERİR Mİ?
nullUser

3
fare imlecini de yakalamanın bir yolu var mı?
Mehdi Karamosly

23

Robot kullanmayı hiç sevmedim, bu yüzden JFrame nesnelerinin ekran görüntülerini yapmak için kendi basit yöntemimi yaptım:

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

17
Robotu sevmemenizin bir nedeni var mı?
Simon Forsberg

2
Bunu sadece bir zevk meselesi olarak düşünün.
DejanLekic

3
Görünüşe göre, ekran görüntüsü alınmadan önce hedef pencere gizlenmiş olsa bile bu çalışma avantajına sahip olmalı.
Brad Mace

7
Öte yandan, bu yalnızca pencerenin içeriğini alır, oysa Robotpencerenin çerçevesini ve başlık çubuğunu da alabilirsiniz.
Brad Mace

1
HiDPI (Mac retina) ekranlar için bu, yarım çözünürlükte ekran görüntüleri oluşturur. ArgFrame.paint (bufferedImage.getGraphics ()) çağrısından önce bufferedImage.getGraphics (). Scale (2, 2) 'yi düzeltmek ve yeni BufferedImage (rec.width * 2, rec.height * 2, BufferedImage.TYPE_INT_ARGB) kullanarak create the BufferedImage
nyholku

18

Tüm monitörleri yakalamak istiyorsanız, aşağıdaki kodu kullanabilirsiniz:

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


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

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

Bir kıyaslama yaptım ve bu en yavaş olanı, ayrıca en büyük kayıp ve en büyük dosya boyutuna sahip. Pardon,
Liam Larsen

3
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 tam bir ekran görüntüsü içerecek, bu üç monitörle test edildi


0

java.awt.RobotBu görevi başarmak için kullanabilirsiniz .

Aşağıda, yakalanan ekran görüntüsünü Dizininize görüntü olarak kaydeden sunucu kodu bulunmaktadır.

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

Ve bu, iş parçacığı üzerinde çalışan ve birkaç dakika sonra kullanıcı ekranının ekran görüntüsünü yakalayan İstemci kodudur.

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

0

Araç Seti, ÜFE'ye dayalı pikselleri döndürür, sonuç olarak Windows'ta ÜFE>% 100 kullanıldığında tüm ekran için bir ekran görüntüsü oluşturulmaz. Bunu yapmayı öneriyorum:

DisplayMode displayMode = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode();
Rectangle screenRectangle = new Rectangle(displayMode.getWidth(), displayMode.getHeight());
BufferedImage screenShot = new Robot().createScreenCapture(screenRectangle);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.