Bildschirmabzüge (Screenshots) und die Frage, ob der Benutzer etwas vor dem Bildschirm tut

Eine sehr interessante Funktion der Robot-Klasse ist createScreenCapture(). Mit ihr lässt sich ein Bildschirmabzug (engl. screenshot) ohne Mauszeiger (zumindest unter Windows, Linux, Solaris und Mac OS X) machen. Die Funktion erwartet als Argument ein Rectangle-Objekt (speichert x, y, height und width), das den zu »fotografierenden« Bereich spezifiziert. Das Ergebnis von createScreenCapture() ist ein BufferedImage-Objekt, das direkt mit ImageIO in eine Datei kommen kann.

BufferedImage bi = new Robot().createScreenCapture(

    new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) );   

ImageIO.write( bi, "jpg", new File("c:/screenshot.jpg") );

Mit createScreenCapture() lassen sich sehr interessante Lösungen realisieren. So lässt sich zum Beispiel überwachen, ob sich Bildschirminhalte ändern. Mit einer Bildanalyse ließe sich auch herausfinden, was der Anwender sich gerade anschaut.

In einem kleinen Beispiel wollen wir feststellen, ob der Benutzer aktiv vom dem Bildschirm ist oder nicht. Wir machen dies an der Anzahl Pixel fest, die sich jede Sekunden verändern. Ein Programm soll dazu jede Sekunde ein Bildschirmabzug nehmen und ausgeben, um wie viel Prozent sich die Pixel gegenüber dem Vorgängerbild verändert haben.

package com.tutego.insel.ui.image;

import java.awt.*;

import java.awt.image.*;

public class ImageDiffs

{

  public static void main( String args[] ) throws Exception

  {

    Rectangle screenSize = new Rectangle( Toolkit.getDefaultToolkit().getScreenSize() );

    BufferedImage image1 = new Robot().createScreenCapture( screenSize );

    while ( true )

    {

      Thread.sleep( 1000 );   

      BufferedImage image2 = new Robot().createScreenCapture( screenSize );

      DataBuffer dataBuffer1 = image1.getData().getDataBuffer();

      DataBuffer dataBuffer2 = image2.getData().getDataBuffer();

      int total = dataBuffer1.getSize(), diff = 0;

      for ( int i = 0; i < total; i++ )

        if ( dataBuffer1.getElem( i ) != dataBuffer2.getElem( i ) )

          diff++;

      System.out.printf( "Pixel total=%d, unterschiedliche Pixel=%d, Unterschied=%.2f%%%n",

                         total, diff, (double) 100 * diff / total );

      image1 = image2;

    }

  }

}

Nach dem der Bildschirmabzug gemacht wurde, gilt es auf die Pixel zuzugreifen und die beiden Bilder zu vergleichen. Um das Bild abzulaufen, könnten wir entweder vom BufferedImage mit den Methode getRGB(int x, int y) arbeiten, oder uns – anders macht es getRGB() auch nicht – das Datenmodel der Grafik holen und es einfach komplett auflaufen; die Größe und Breite der beiden Bildschirmabzüge ist ja immer gleich, und so spielt die Höhe und Breite keine Rolle. Von den beiden DataBuffer-Objekten, die die Rohdaten der Grafik repräsentieren, erfragt getElem() den Farbwert und wenn es Unterschiede gibt, inkrementiert das Programm einen Zähler. Nach dem Ablaufen aller Werte gibt es eine Statistik, die etwa so beginnen kann:

Pixel total=2304000, unterschiedliche Pixel=297, Unterschied=0,01%

Pixel total=2304000, unterschiedliche Pixel=1708, Unterschied=0,07%

Pixel total=2304000, unterschiedliche Pixel=1689, Unterschied=0,07%

Pixel total=2304000, unterschiedliche Pixel=1000568, Unterschied=43,43%

Pixel total=2304000, unterschiedliche Pixel=1002525, Unterschied=43,51%

Pixel total=2304000, unterschiedliche Pixel=2087, Unterschied=0,09%

Labels:

2 Antwort(en) auf ›Bildschirmabzüge (Screenshots) und die Frage, ob der Benutzer etwas vor dem Bildschirm tut‹

  1. # Anonymous Anonym

    Also wenn jede Sekunde pixel für pixel der Bildschirm überprüft wird, kann der Benutzer ja auch nichts machen, weil der Rechner dann schon ausgelastet ist, oder  

  2. # Blogger Christian Ullenboom

    Jeder ist freigestellt, hier eine Verzögerung einzubauen. Ich war überrascht, das mein System gut bedienbar war. Naja, mit 4 Kernen ... :)  

Kommentar veröffentlichen