Java获取屏幕真实分辨率

这个问题大家可能不陌生,一搜索,就一堆答案,大多是一行代码搞定

Toolkit.getDefaultToolkit().getScreenSize();

然而简单做了一个测试,效果如下,输出1707x960,而我电脑的分辨率是3840x2160,根本就不对

错误原因

Toolkit.getDefaultToolkit().getScreenSize()这种方式取得的屏幕尺寸没有考虑缩放问题,如果windows设置缩放不是100%,那么上述方法将取不到正确的之后,如下图,缩放设置的是225%,而1707x960和电脑的真实分辨率3840x2160正好差了225%倍

异常原因

       由于windows设置了缩放比例,Toolkit.getDefaultToolkit().getScreenSize()并不能拿到真实的分辨率,拿到的屏幕的分辨率与真实分辨率正好差了缩放比例的倍数,可是这个缩放比例又没有接口可以弄到,这个是非常特殊的API,估计只有掉windows api,才能拿到这个参数,这个缩放比例无法通过正常途径获取,那么我们无法将Toolkit.getDefaultToolkit().getScreenSize();的分辨率换算成真实分辨率,也就是说Toolkit这种方法获取分辨率根本不可行,只能另寻出路

解决方案

本人查阅了大量的国内外论坛,至今没有发现这个问题的解决方案,国外有好多老外也有此问题,然而至今没有解决

本人反复调研,偶然间发现了一个屏幕截图的接口

BufferedImage bi = (new Robot()).createScreenCapture(new Rectangle(x, y, width, height));

这行代码,可以实现将屏幕上一个区域截取成一个图片,经过测试,这个图片和屏幕的分辨率是匹配的,因此我们可以利用这个接口,拿到屏幕的分辨率,具体原理如下:

      以(0,0)为起点截取一个足够大的图片,当这个图片足够大(超出屏幕大小时)时,这个图片的右侧和下侧会超出屏幕的尺寸,那么截取来的图片右侧和下侧,会有一条黑色的边缘,因此我们用截取图片的大小减去右侧和下侧边缘的尺寸,就是屏幕的大小

实现源码如下:

package test;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

public class TestScreenSize {
	public static BufferedImage getScreenImage(int x, int y, int width, int height) {
		try {
			return (new Robot()).createScreenCapture(new Rectangle(x, y, width, height));
		} catch (Exception e) {
			return null;
		}
	}

	public static Dimension getScreenSize() {
		return getScreenSizeFromImage(getScreenImage(0, 0, 10000, 5000));
	}

	private static Dimension getScreenSizeFromImage(BufferedImage image) {
		if (image == null) {
			return Toolkit.getDefaultToolkit().getScreenSize();
		}
		int width = image.getWidth();
		int height = image.getHeight();
		long[] w = new long[width];
		long[] h = new long[height];
		for (int i = 0; i < width; i++) {
			long value = 0;
			for (int j = 0; j < height; j++) {
				value += image.getRGB(i, j);
			}
			w[i] = value;
		}
		for (int i = 0; i < height; i++) {
			long value = 0;
			for (int j = 0; j < width; j++) {
				value += image.getRGB(j, i);
			}
			h[i] = value;
		}
		return new Dimension(getValidSize(w), getValidSize(h));
	}

	private static int getValidSize(long[] v) {
		if (v == null || v.length == 0) {
			return 0;
		}
		long last = v[v.length - 1];
		for (int i = v.length - 1; i >= 0; i--) {
			if (last != v[i]) {
				return i + 1;
			}
		}
		return 0;
	}
	public static void main(String[] args) {
		System.out.println(getScreenSize());
	}
}

经过测试效果如下:

可见,此时,我们拿到了真实的分辨率

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值