Screenshots werden mit schwarzen Bereichen aufgefüllt?

Hallo,
ich habe hier schon ein Thema offen und im Zuge dessen will ich von einem Bildschirmbereich (gegeben durch die Pixelkoordinaten vom Punkt oben links und unten rechts) ein jpg Bild anfertigen.
Ich komme heirbei auf diesen Code:

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;


public class screen2image{

    public void robo(int x1, int y1, int x2, int y2) throws Exception
    {
        Robot robot = new Robot();
        BufferedImage screenShot = robot.createScreenCapture(new Rectangle(x1,y1,x2-x1,y2-y1));
				//new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())
        ImageIO.write(screenShot, "JPG", new File("C:\\Users\\d-sch\\Desktop\\Java Dateien\\Megasystem Bot\\ScreenshotArea.jpg"));
    }

/*
    public void robo() throws Exception
    {
        Calendar now = Calendar.getInstance();
        Robot robot = new Robot();
        BufferedImage screenShot = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
				//new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())
        ImageIO.write(screenShot, "JPG", new File("C:\\Users\\d-sch\\Desktop\\Java Dateien\\Megasystem Bot\\Screenshot.jpg"));
        System.out.println(formatter.format(now.getTime()));
    }
*/

    public static void main(String[] args) throws Exception
    {
        screen2image s2i = new screen2image();
        Thread.sleep(2000);//2 seconds pause
				int x1=0;
				int y1=0;
				GraphicsDevice gd =      GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
				int width = gd.getDisplayMode().getWidth();
				int height = gd.getDisplayMode().getHeight();
				int x2=1920;
				int y2=1080;
				System.out.println("Bildschirm Maße: x="+width+", y="+height);
        s2i.robo(x1,y1,x2,y2);
    }
}

Anfangs hatte ich, wie in der Auskommentierten Funktion, mit dem Toolkit und dessen Methode getScreesize gearbeitet. Funktionierte zumindest für den Screenshot des vollen bildschirms auch gut, nur stellte ich beim eher zufälligen Anzeigenlassen der erhaltenen „Länge und Breite“ fest dass die Ergebnis nicht zur wirklichen Auflösung passt.
Wie ich beim Googeln rausfand, hängt das damit zusammen dass ich bei Windows nicht die 100% Skalierung benutze sondern (glaube ich) nur 90%.
Da ich nicht gedenke, nur hierfür meine Skalierung zu ändern, suchte ich also weiter.

Ein Forumsthread empfahl stattdessen die Variante mit dem GraphicsDevice zu verwenden die auch in der Main methode da vorkommt.

jpg Datei wird erstellt, kein Problem.
Allerdings wenn ich mir das Bild dann angucke, ist oben links der Screenshotinhalt und unten und rechts ist das Bild mit schwarzem bereich sozusagen „aufgefüllt“, vermutlich wird hier aus irgendeinem grund versucht, durch Füllen des Reste mit schwarz, eine gewisse Bildgröße sicherzustellen, auch wenn meiN Screenshot nur einige Pixel breit und lang wäre.
(siehe weiter unten das Bild. DIe schwarzen Bereiche wurden, warum auch immer, gegen meinen Willen hinzugefügt!)

Das ist natürlich nicht in meinem Sinn, ich will ja in der Bilddatei nur den Bereich habe, nicht noch irgendwelche ergänzten Schwarzbereiche.

Die Java Dokumentation ist da natürlich hilfreich wie nochwas, in dieser steht zur CreateScreencapture(…) Methode nur „Returns: The captured image“

Also nix dazu was er in welcher Größe erzeugt oder notfalls auffüllt oder so. :-/

Kennt sich jemand da aus?
Ich habe die Methoden nur aus den betreffenden Forenbeiträgen übernommen und nur wenig Plan, was da warum passiert.

Wobei, logisch gedacht, dürfte das Problem eigentlich durch die robot methode entstehen.

Als ich allerdings anfangs die auskommentierte robo() Methode benutzte, die über toolkit die Maße bestimmt, da bestand die bilddatei wirklich nur aus dem Screenshotinhalt.
Also nichts mit Schwarzbereich aufgefüllt oder so.

Viel Text, aber es ist schwer, da die konkrete Frage rauszuschälen. Falls ich das richtig interpretiere, könnte das mit irgendwelchem Windows-Eigenen Skalieren zu tun haben. Nur als ersten, schnellen Test, eher aus Neugier: Was gibt denn

    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    System.out.println(gd.getDefaultConfiguration().getDefaultTransform());
    System.out.println(gd.getDefaultConfiguration().getNormalizingTransform());

bei dir aus?

Das gibt mir auf der Konsole die Ausgabe

AffineTransform[[1.25, 0.0, 0.0], [0.0, 1.25, 0.0]]
AffineTransform[[1.666666666666667, 0.0, 0.0], [0.0, 1.666666666666667, 0.0]]

was auch immer das bedeuten mag :slight_smile:

Die 1.25 sind der schwarze Rand. Oder besser gesagt: Wenn da 1.0 stünde, wäre der schwarze Rand nicht da.

Wie man das nun am geschicktesten, allgemeingültigsten und elegantesten vermeidet, weiß ich auch nicht auswendig. Man kann es natürlich ganz pragmatisch rausrechnen…

    public static void main(String[] args) throws Exception
    {
        GraphicsEnvironment ge = 
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        DisplayMode dm = gd.getDisplayMode();
        int width = dm.getWidth();
        int height = dm.getHeight();
        
        GraphicsConfiguration gc = gd.getDefaultConfiguration();
        AffineTransform at = gc.getDefaultTransform();
        double scaleX = at.getScaleX();
        double scaleY = at.getScaleY();
        int imageW = (int)(width / scaleX);
        int imageH = (int)(height / scaleY);

        System.out.println("Bildschirm Maße: x=" + width + ", y=" + height);
        System.out.println("Image size " + imageW + " " + imageH);
        
        //screen2image s2i = new screen2image();
        //Thread.sleep(2000);//2 seconds pause
        //s2i.robo(x1,y1,x2,y2);
        
        
    }

Aber ob es da was besseres gibt (oder welche „Stolpersteine“ das später verursacht) ist schwer zu sagen. (Wirklich testen kann ich es auch nicht - bei mir sind die Faktoren 1.0…)