2

My Java application takes a screenshot of the screen and then displays it. Normally this would be a funny prank where a user would click around and there would be no response as they're trying to interact with an image.

However, if the user has Display scaling set on Windows, to 125% for example (pretty much required for larger monitors otherwise your text/icons will be very small), then when I use a JFrame to display their 1920x1080 BufferedImage, it is instead displayed at 2400x1350 as a blurry pixelated mess. Obviously the prank would not work in this case.

How can I make this work as intended regardless of what a user has set for their display scaling?

Code:

import java.awt.Dimension;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinDef.HWND;


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

        BufferedImage capture = captureNotepadWindow();
        int width = capture.getWidth();
        int height =  capture.getHeight();
        System.out.println(width + "," + height);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new JLabel(new ImageIcon(capture)));
        frame.setPreferredSize(new Dimension(width, height));
        frame.setUndecorated(true);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

    public static BufferedImage captureNotepadWindow() throws Exception {
        // Find notepad window handle
        HWND notepadHwnd = User32.INSTANCE.FindWindow("Notepad", null);
        if (notepadHwnd == null) {
            throw new Exception("Notepad window not found");
        }
        return GDI32Util.getScreenshot(notepadHwnd);
    }

}

Did not work, result is a pixelated upscaled image. I also tried to scale the image down by 1/1.25 such that the scaling by Windows would return it to the original size, but the image was very pixelated due to all the scaling.

11
  • most probably the problem comes from taking the screenshot...you want a 1920x1080 image in the first place Commented May 29, 2024 at 4:11
  • @PerdiEstaquel In my code above, I checked the width and height used when setting Dimension object, and it is indeed 1920x1080. Commented May 29, 2024 at 4:21
  • In order for me to help you debug your code, I need to reproduce your problem and I cannot do that since the code in your question is not a minimal reproducible example because it does not contain the declaration of variable displayImage nor how that variable is assigned a value. Commented May 29, 2024 at 4:50
  • @Abra I have edited my post to include a full example which reproduces the issue. Please change your display scaling on a Windows machine to 125%+. Then type some text into a notepad instance, and run the above code. Then compare your running notepad instance to the screenshot displayed. You will see that when printing out the dimensions, it displays the width and height of your running notepad instance. However, the image displayed via JFrame is NOT the same width/height, and gets scaled by the Windows Display scaling value. Commented May 29, 2024 at 6:21
  • Did you try getting the screen capture via class java.awt.Robot? Commented May 29, 2024 at 6:57

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.