簡體   English   中英

如何獲得 Python 中的顯示器分辨率?

[英]How do I get monitor resolution in Python?

獲得監視器分辨率的最簡單方法是什么(最好在元組中)?

在 Windows 中,您還可以將 ctypes 與GetSystemMetrics()

import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)

這樣你就不需要安裝 pywin32 包; 它不需要 Python 本身沒有的任何東西。

對於多顯示器設置,您可以檢索虛擬顯示器的組合寬度和高度:

import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(78), user32.GetSystemMetrics(79)

為此,我創建了一個PyPI 模塊

pip install screeninfo

編碼:

from screeninfo import get_monitors
for m in get_monitors():
    print(str(m))

結果:

monitor(1920x1080+1920+0)
monitor(1920x1080+0+0)

它支持多顯示器環境 它的目標是跨平台; 現在它支持 Cygwin 和 X11,但完全歡迎拉取請求。

在 Windows 上:

from win32api import GetSystemMetrics

print("Width =", GetSystemMetrics(0))
print("Height =", GetSystemMetrics(1))

如果您使用高分辨率屏幕,請確保您的 Python 解釋器是 HIGHDPIAWARE。

基於這篇文章。

直接取自這篇文章的答案: How to get the screen size in Tkinter?

import tkinter as tk

root = tk.Tk()

screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

如果您使用的是 wxWindows,您可以簡單地執行以下操作:

import wx

app = wx.App(False) # the wx.App object must be created first.    
print(wx.GetDisplaySize())  # returns a tuple

在 Windows 8.1 上,我沒有從 ctypes 或 tk 獲得正確的分辨率。 其他人對 ctypes 也有同樣的問題: getsystemmetrics 返回錯誤的屏幕尺寸要在 Windows 8.1 上獲得高 DPI 監視器的正確全分辨率,必須調用 SetProcessDPIAware 並使用以下代碼:

import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

完整詳情如下:

我發現這是因為 Windows 報告了縮放分辨率。 默認情況下,python 似乎是一個“系統 dpi 感知”應用程序。 此處列出了 DPI 感知應用程序的類型: http : //msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor

基本上,不是以完整的顯示器分辨率顯示內容,這會使字體變小,而是將內容按比例放大,直到字體足夠大。

在我的顯示器上,我得到:
物理分辨率:2560 x 1440 (220 DPI)
報告的 python 分辨率:1555 x 875 (158 DPI)

根據此 Windows 站點: http : //msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx報告系統有效分辨率的公式為:(reported_px*current_dpi)/(96 dpi ) = 物理像素

我能夠使用以下代碼獲得正確的全屏分辨率和當前 DPI。 請注意,我調用 SetProcessDPIAware() 以允許程序查看真實分辨率。

import tkinter as tk
root = tk.Tk()

width_px = root.winfo_screenwidth()
height_px = root.winfo_screenheight() 
width_mm = root.winfo_screenmmwidth()
height_mm = root.winfo_screenmmheight() 
# 2.54 cm = in
width_in = width_mm / 25.4
height_in = height_mm / 25.4
width_dpi = width_px/width_in
height_dpi = height_px/height_in 

print('Width: %i px, Height: %i px' % (width_px, height_px))
print('Width: %i mm, Height: %i mm' % (width_mm, height_mm))
print('Width: %f in, Height: %f in' % (width_in, height_in))
print('Width: %f dpi, Height: %f dpi' % (width_dpi, height_dpi))

import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
print('Size is %f %f' % (w, h))

curr_dpi = w*96/width_px
print('Current DPI is %f' % (curr_dpi))    

哪個返回:

Width: 1555 px, Height: 875 px
Width: 411 mm, Height: 232 mm
Width: 16.181102 in, Height: 9.133858 in
Width: 96.099757 dpi, Height: 95.797414 dpi
Size is 2560.000000 1440.000000
Current DPI is 158.045016

我正在運行帶有 220 DPI 顯示器的 Windows 8.1。 我的顯示縮放將我當前的 DPI 設置為 158。

我將使用 158 來確保我的 matplotlib 圖大小合適: from pylab import rcParams rcParams['figure.dpi'] = curr_dpi

為了完整起見,Mac OS X

import AppKit
[(screen.frame().size.width, screen.frame().size.height)
    for screen in AppKit.NSScreen.screens()]

將為您提供包含所有屏幕尺寸的元組列表(如果存在多個顯示器)

如果您專門使用Qt工具包PySide ,您可以執行以下操作:

from PySide import QtGui
import sys

app = QtGui.QApplication(sys.argv)
screen_rect = app.desktop().screenGeometry()
width, height = screen_rect.width(), screen_rect.height()

使用Linux,最簡單的方法是執行bash命令

xrandr | grep '*'

並使用正則表達式解析其輸出。

你也可以通過 PyGame: http ://www.daniweb.com/forums/thread54881.html

一種跨平台且簡單的方法是使用幾乎所有 python 版本附帶的 TKinter,因此您無需安裝任何東西:

import tkinter
root = tkinter.Tk()
root.withdraw()
WIDTH, HEIGHT = root.winfo_screenwidth(), root.winfo_screenheight()

這是一個快速的小 Python 程序,它將顯示有關您的多顯示器設置的信息:

import gtk

window = gtk.Window()

# the screen contains all monitors
screen = window.get_screen()
print "screen size: %d x %d" % (gtk.gdk.screen_width(),gtk.gdk.screen_height())

# collect data about each monitor
monitors = []
nmons = screen.get_n_monitors()
print "there are %d monitors" % nmons
for m in range(nmons):
  mg = screen.get_monitor_geometry(m)
  print "monitor %d: %d x %d" % (m,mg.width,mg.height)
  monitors.append(mg)

# current monitor
curmon = screen.get_monitor_at_window(screen.get_active_window())
x, y, width, height = monitors[curmon]
print "monitor %d: %d x %d (current)" % (curmon,width,height)  

這是其輸出的示例:

screen size: 5120 x 1200
there are 3 monitors
monitor 0: 1600 x 1200
monitor 1: 1920 x 1200
monitor 2: 1600 x 1200
monitor 1: 1920 x 1200 (current)

擴展@user2366975的答案,使用 Tkinter(Python 2/3 中的代碼)在多屏設置中獲取當前屏幕尺寸:

try:
    # for Python 3
    import tkinter as tk
except ImportError:
    # for Python 2
    import Tkinter as tk


def get_curr_screen_geometry():
    """
    Workaround to get the size of the current screen in a multi-screen setup.

    Returns:
        geometry (str): The standard Tk geometry string.
            [width]x[height]+[left]+[top]
    """
    root = tk.Tk()
    root.update_idletasks()
    root.attributes('-fullscreen', True)
    root.state('iconic')
    geometry = root.winfo_geometry()
    root.destroy()
    return geometry

(應該跨平台工作,僅在 Linux 上測試)

老問題,但缺少這個。 我是 python 新手,所以請告訴我這是否是一個“糟糕”的解決方案。 此解決方案僅適用於 Windows 和 MacOS,並且僅適用於主屏幕 - 但問題中未提及操作系統。

通過截取屏幕來測量尺寸。 由於屏幕尺寸不應該改變,這必須只做一次。 如果您安裝了 GTK、wx 等 gui 工具包,還有更優雅的解決方案。

枕頭

pip install Pillow

from PIL import ImageGrab

img = ImageGrab.grab()
print (img.size)

我在我的一個項目中使用了 get_screen_resolution 方法,如下所示,它基本上是一個導入鏈。 您可以根據您的需要通過移除那些不需要的部分並在鏈中向上移動更可能的端口來修改它。

PYTHON_V3 = sys.version_info >= (3,0,0) and sys.version_info < (4,0,0):
#[...]
    def get_screen_resolution(self, measurement="px"):
        """
        Tries to detect the screen resolution from the system.
        @param measurement: The measurement to describe the screen resolution in. Can be either 'px', 'inch' or 'mm'. 
        @return: (screen_width,screen_height) where screen_width and screen_height are int types according to measurement.
        """
        mm_per_inch = 25.4
        px_per_inch =  72.0 #most common
        try: # Platforms supported by GTK3, Fx Linux/BSD
            from gi.repository import Gdk 
            screen = Gdk.Screen.get_default()
            if measurement=="px":
                width = screen.get_width()
                height = screen.get_height()
            elif measurement=="inch":
                width = screen.get_width_mm()/mm_per_inch
                height = screen.get_height_mm()/mm_per_inch
            elif measurement=="mm":
                width = screen.get_width_mm()
                height = screen.get_height_mm()
            else:
                raise NotImplementedError("Handling %s is not implemented." % measurement)
            return (width,height)
        except:
            try: #Probably the most OS independent way
                if PYTHON_V3: 
                    import tkinter 
                else:
                    import Tkinter as tkinter
                root = tkinter.Tk()
                if measurement=="px":
                    width = root.winfo_screenwidth()
                    height = root.winfo_screenheight()
                elif measurement=="inch":
                    width = root.winfo_screenmmwidth()/mm_per_inch
                    height = root.winfo_screenmmheight()/mm_per_inch
                elif measurement=="mm":
                    width = root.winfo_screenmmwidth()
                    height = root.winfo_screenmmheight()
                else:
                    raise NotImplementedError("Handling %s is not implemented." % measurement)
                return (width,height)
            except:
                try: #Windows only
                    from win32api import GetSystemMetrics 
                    width_px = GetSystemMetrics (0)
                    height_px = GetSystemMetrics (1)
                    if measurement=="px":
                        return (width_px,height_px)
                    elif measurement=="inch":
                        return (width_px/px_per_inch,height_px/px_per_inch)
                    elif measurement=="mm":
                        return (width_px/mm_per_inch,height_px/mm_per_inch)
                    else:
                        raise NotImplementedError("Handling %s is not implemented." % measurement)
                except:
                    try: # Windows only
                        import ctypes
                        user32 = ctypes.windll.user32
                        width_px = user32.GetSystemMetrics(0)
                        height_px = user32.GetSystemMetrics(1)
                        if measurement=="px":
                            return (width_px,height_px)
                        elif measurement=="inch":
                            return (width_px/px_per_inch,height_px/px_per_inch)
                        elif measurement=="mm":
                            return (width_px/mm_per_inch,height_px/mm_per_inch)
                        else:
                            raise NotImplementedError("Handling %s is not implemented." % measurement)
                    except:
                        try: # Mac OS X only
                            import AppKit 
                            for screen in AppKit.NSScreen.screens():
                                width_px = screen.frame().size.width
                                height_px = screen.frame().size.height
                                if measurement=="px":
                                    return (width_px,height_px)
                                elif measurement=="inch":
                                    return (width_px/px_per_inch,height_px/px_per_inch)
                                elif measurement=="mm":
                                    return (width_px/mm_per_inch,height_px/mm_per_inch)
                                else:
                                    raise NotImplementedError("Handling %s is not implemented." % measurement)
                        except: 
                            try: # Linux/Unix
                                import Xlib.display
                                resolution = Xlib.display.Display().screen().root.get_geometry()
                                width_px = resolution.width
                                height_px = resolution.height
                                if measurement=="px":
                                    return (width_px,height_px)
                                elif measurement=="inch":
                                    return (width_px/px_per_inch,height_px/px_per_inch)
                                elif measurement=="mm":
                                    return (width_px/mm_per_inch,height_px/mm_per_inch)
                                else:
                                    raise NotImplementedError("Handling %s is not implemented." % measurement)
                            except:
                                try: # Linux/Unix
                                    if not self.is_in_path("xrandr"):
                                        raise ImportError("Cannot read the output of xrandr, if any.")
                                    else:
                                        args = ["xrandr", "-q", "-d", ":0"]
                                        proc = subprocess.Popen(args,stdout=subprocess.PIPE)
                                        for line in iter(proc.stdout.readline,''):
                                            if isinstance(line, bytes):
                                                line = line.decode("utf-8")
                                            if "Screen" in line:
                                                width_px = int(line.split()[7])
                                                height_px = int(line.split()[9][:-1])
                                                if measurement=="px":
                                                    return (width_px,height_px)
                                                elif measurement=="inch":
                                                    return (width_px/px_per_inch,height_px/px_per_inch)
                                                elif measurement=="mm":
                                                    return (width_px/mm_per_inch,height_px/mm_per_inch)
                                                else:
                                                    raise NotImplementedError("Handling %s is not implemented." % measurement)
                                except:
                                    # Failover
                                    screensize = 1366, 768
                                    sys.stderr.write("WARNING: Failed to detect screen size. Falling back to %sx%s" % screensize)
                                    if measurement=="px":
                                        return screensize
                                    elif measurement=="inch":
                                        return (screensize[0]/px_per_inch,screensize[1]/px_per_inch)
                                    elif measurement=="mm":
                                        return (screensize[0]/mm_per_inch,screensize[1]/mm_per_inch)
                                    else:
                                        raise NotImplementedError("Handling %s is not implemented." % measurement)

XWindows 版本:

#!/usr/bin/python

import Xlib
import Xlib.display

resolution = Xlib.display.Display().screen().root.get_geometry()
print str(resolution.width) + "x" + str(resolution.height)

如果您安裝了 PyQt4,請嘗試以下代碼:

from PyQt4 import QtGui
import sys

MyApp = QtGui.QApplication(sys.argv)
V = MyApp.desktop().screenGeometry()
h = V.height()
w = V.width()
print("The screen resolution (width X height) is the following:")
print(str(w) + "X" + str(h))

對於 PyQt5,以下將起作用:

from PyQt5 import QtWidgets
import sys

MyApp = QtWidgets.QApplication(sys.argv)
V = MyApp.desktop().screenGeometry()
h = V.height()
w = V.width()
print("The screen resolution (width X height) is the following:")
print(str(w) + "X" + str(h))

在 Linux 上:

import subprocess
import re

def getScreenDimensions():
    xrandrOutput = str(subprocess.Popen(['xrandr'], stdout=subprocess.PIPE).communicate()[0])
    matchObj = re.findall(r'current\s(\d+) x (\d+)', xrandrOutput)
    if matchObj:
        return (int(matchObj[0][0]), int(matchObj[0][1]))

screenWidth, screenHeight = getScreenDimensions()
print(f'{screenWidth} x {screenHeight}')

試試 pyautogui:

import pyautogui
resolution = pyautogui.size()
print(resolution) 

使用 Linux 而不是 regexp 取第一行並取出當前分辨率值。

當前顯示分辨​​率:0

>>> screen = os.popen("xrandr -q -d :0").readlines()[0]
>>> print screen
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 1920 x 1920
>>> width = screen.split()[7]
>>> print width
1920
>>> height = screen.split()[9][:-1]
>>> print height
1080
>>> print "Current resolution is %s x %s" % (width,height)
Current resolution is 1920 x 1080

這是在 xrandr 1.3.5 上完成的,我不知道其他版本的輸出是否不同,但這應該很容易弄清楚。

使用pygame

import pygame
pygame.init()
infos = pygame.display.Info()
screen_size = (infos.current_w, infos.current_h)

[1]

但是,如果您嘗試將窗口設置為屏幕大小,您可能只想執行以下操作:

pygame.display.set_mode((0,0),pygame.FULLSCREEN)

將您的顯示器設置為全屏模式。 [2]

比賽遲到了。 我想我發現跨平台使用支持多顯示器的無依賴庫mss ( https://pypi.org/project/mss/ ):

import mss
sct=mss.mss()
sct.monitors

然后你會得到這樣的東西:

[{'left': -1440, 'top': 0, 'width': 4000, 'height': 1080},
 {'left': 0, 'top': 0, 'width': 2560, 'height': 1080},
 {'left': -1440, 'top': 180, 'width': 1440, 'height': 900}]

元素 0 是組合所有監視器的虛擬屏幕。 元素 1 是主監視器,元素 2 是第二監視器。

獲取每像素位數:

import ctypes
user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32

screensize = (user32.GetSystemMetrics(0), user32.GetSystemMetrics(1))
print "screensize =%s"%(str(screensize))
dc = user32.GetDC(None);

screensize = (gdi32.GetDeviceCaps(dc,8), gdi32.GetDeviceCaps(dc,10), gdi32.GetDeviceCaps(dc,12))
print "screensize =%s"%(str(screensize))
screensize = (gdi32.GetDeviceCaps(dc,118), gdi32.GetDeviceCaps(dc,117), gdi32.GetDeviceCaps(dc,12))
print "screensize =%s"%(str(screensize))

gdi32 中的參數:

#/// Vertical height of entire desktop in pixels
#DESKTOPVERTRES = 117,
#/// Horizontal width of entire desktop in pixels
#DESKTOPHORZRES = 118,
#/// Horizontal width in pixels
#HORZRES = 8,
#/// Vertical height in pixels
#VERTRES = 10,
#/// Number of bits per pixel
#BITSPIXEL = 12,

使用xrandr另一個版本:

import re
from subprocess import run, PIPE

output = run(['xrandr'], stdout=PIPE).stdout.decode()
result = re.search(r'current (\d+) x (\d+)', output)
width, height = map(int, result.groups()) if result else (800, 600)

如果您使用的是 Windows 操作系統,則可以使用 OS 模塊來獲取它:

import os
cmd = 'wmic desktopmonitor get screenheight, screenwidth'
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))

它將返回一個元組(Y,X) ,其中Y是垂直尺寸, X是水平尺寸。 此代碼適用於 Python 2 和 Python 3

更新

對於 Windows 8/8.1/10,上述答案不起作用,請改用下一個:

import os
cmd = "wmic path Win32_VideoController get CurrentVerticalResolution,CurrentHorizontalResolution"
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))

許多這些答案使用 tkinter 來查找屏幕高度/寬度(分辨率),但有時有必要知道您的屏幕跨平台兼容的dpi 這個答案來自這個鏈接,並作為另一篇文章的評論留下,但花了幾個小時的搜索才找到。 我還沒有遇到任何問題,但是如果它在您的系統上不起作用,請告訴我!

import tkinter
root = tkinter.Tk()
dpi = root.winfo_fpixels('1i')

這方面的文檔說:

winfo_fpixels(number)
# Return the number of pixels for the given distance NUMBER (e.g. "3c") as float

距離數字是一個數字后跟一個單位,因此 3c 表示 3 厘米,該函數給出了屏幕 3 厘米上的像素數(見此處)。 因此,為了獲得 dpi,我們要求函數提供 1 英寸屏幕(“1i”)中的像素數。

你可以使用PyMouse 要獲取屏幕尺寸,只需使用screen_size()屬性:

from pymouse import PyMouse
m = PyMouse()
a = m.screen_size()

a將返回一個元組(X, Y) ,其中X是水平位置, Y是垂直位置。

鏈接到文檔中的函數。

對於更高版本的 PyGtk:

import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk

display = Gdk.Display.get_default()
n_monitors = display.get_n_monitors()
print("there are %d monitors" % n_monitors)
for m in range(n_monitors):
  monitor = display.get_monitor(m)
  geometry = monitor.get_geometry()
  print("monitor %d: %d x %d" % (m, geometry.width, geometry.height))

對於 Linux,你可以使用這個:

import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk

s = Gdk.Screen.get_default()
screen_width = s.get_width()
screen_height = s.get_height()
print(screen_width)
print(screen_height)

在 Linux 上我們可以使用 subprocess 模塊

import subprocess
cmd = ['xrandr']
cmd2 = ['grep', '*']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
p2 = subprocess.Popen(cmd2, stdin=p.stdout, stdout=subprocess.PIPE)
p.stdout.close()

resolution_string, junk = p2.communicate()
resolution = resolution_string.split()[0]
resolution = resolution.decode("utf-8") 
width = int(resolution.split("x")[0].strip())
heigth = int(resolution.split("x")[1].strip())

視網膜屏幕有點麻煩,我使用 tkinter 獲取假大小,使用枕頭抓取獲取真實大小:

import tkinter
root = tkinter.Tk()
resolution_width = root.winfo_screenwidth()
resolution_height = root.winfo_screenheight()
image = ImageGrab.grab()
real_width, real_height = image.width, image.height
ratio_width = real_width / resolution_width
ratio_height = real_height/ resolution_height

使用pynput庫的實用程序腳本。 在這里發布以供參考:

 
from pynput.mouse import Controller as MouseController

def get_screen_size():
    """Utility function to get screen resolution"""

    mouse = MouseController()

    width = height = 0

    def _reset_mouse_position():
        # Move the mouse to the top left of 
        # the screen
        mouse.position = (0, 0)

    # Reset mouse position
    _reset_mouse_position()

    count = 0
    while 1:
        count += 1
        mouse.move(count, 0)
        
        # Get the current position of the mouse
        left = mouse.position[0]

        # If the left doesn't change anymore, then
        # that's the screen resolution's width
        if width == left:
            # Add the last pixel
            width += 1

            # Reset count for use for height
            count = 0
            break

        # On each iteration, assign the left to 
        # the width
        width = left
    
    # Reset mouse position
    _reset_mouse_position()

    while 1:
        count += 1
        mouse.move(0, count)

        # Get the current position of the mouse
        right = mouse.position[1]

        # If the right doesn't change anymore, then
        # that's the screen resolution's height
        if height == right:
            # Add the last pixel
            height += 1
            break

        # On each iteration, assign the right to 
        # the height
        height = right

    return width, height

>>> get_screen_size()
(1920, 1080)

嘗試使用pyautogui.size()

import pyautogui #pip install pyautogui

x = pyautogui.size()[0] # getting the width of the screen
y = pyautogui.size()[1] # getting the length of the screen

print(x,y) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM