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

What is the simplest way to get monitor resolution (preferably in a tuple)?

This question is related to python screen resolution

The answer is


Using pygame:

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

[1]

However, if you're trying to set your window to the size of the screen, you might just want to do:

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

to set your display to fullscreen mode. [2]


On 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}')

In Windows, you can also use ctypes with GetSystemMetrics():

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

so that you don't need to install the pywin32 package; it doesn't need anything that doesn't come with Python itself.

For multi-monitor setups, you can retrieve the combined width and height of the virtual monitor:

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

It's a little troublesome for retina screen, i use tkinter to get the fake size, use pilllow grab to get real size :

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

If you are using the Qt toolkit specifically PySide, you can do the following:

from PySide import QtGui
import sys

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

I am using a get_screen_resolution method in one of my projects like the one below, which is basically an import chain. You can modify this according to Your needs by removing those parts that are not needed and move more likely ports upwards in the chain.

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)

Utility script using pynput library. Posting here for ref.:

 
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)

For Linux, you can use this:

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)

Here is a quick little Python program that will display the information about your multi-monitor setup:

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)  

Here's an example of its output:

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)

On Linux we can use subprocess module

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())

A lot of these answers use tkinter to find the screen height/width (resolution), but sometimes it is necessary to know the dpi of your screen cross-platform compatible. This answer is from this link and left as a comment on another post, but it took hours of searching to find. I have not had any issues with it yet, but please let me know if it does not work on your system!

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

The documentation for this says:

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

A distance number is a digit followed by a unit, so 3c means 3 centimeters, and the function gives the number of pixels on 3 centimeters of the screen (as found here). So to get dpi, we ask the function for the number of pixels in 1 inch of screen ("1i").


Try pyautogui:

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

For later versions of 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))

To get bits per pixel:

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))

parameters in 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,

Using Linux Instead of regexp take the first line and take out the current resolution values.

Current resolution of display :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

This was done on xrandr 1.3.5, I don't know if the output is different on other versions, but this should make it easy to figure out.


Taken directly from an answer to this post: 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()

If you are working on Windows OS, you can use OS module to get it:

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

It will return a tuple (Y,X) where Y is the vertical size and X is the horizontal size. This code works on Python 2 and Python 3


Old question but this is missing. I'm new to python so please tell me if this is a "bad" solution. This solution is supported for Windows and MacOS only and it works just for the main screen - but the os is not mentioned in the question.

Measure the size by taking a screenshot. As the screensize should not change this has to be done only once. There are more elegant solutions if you have a gui toolkit like GTK, wx, ... installed.

see Pillow

pip install Pillow

from PIL import ImageGrab

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

A cross platform and easy way to do this is by using TKinter that comes with nearly all the python versions so you don't have to install anything:

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

If you're using wxWindows, you can simply do:

import wx

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

On Windows 8.1 I am not getting the correct resolution from either ctypes or tk. Other people are having this same problem for ctypes: getsystemmetrics returns wrong screen size To get the correct full resolution of a high DPI monitor on windows 8.1, one must call SetProcessDPIAware and use the following code:

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

Full Details Below:

I found out that this is because windows is reporting a scaled resolution. It appears that python is by default a 'system dpi aware' application. Types of DPI aware applications are listed here: http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor

Basically, rather than displaying content the full monitor resolution, which would make fonts tiny, the content is scaled up until the fonts are big enough.

On my monitor I get:
Physical resolution: 2560 x 1440 (220 DPI)
Reported python resolution: 1555 x 875 (158 DPI)

Per this windows site: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx The formula for reported system effective resolution is: (reported_px*current_dpi)/(96 dpi) = physical_px

I'm able to get the correct full screen resolution, and current DPI with the below code. Note that I call SetProcessDPIAware() to allow the program to see the real resolution.

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))    

Which returned:

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

I am running windows 8.1 with a 220 DPI capable monitor. My display scaling sets my current DPI to 158.

I'll use the 158 to make sure my matplotlib plots are the right size with: from pylab import rcParams rcParams['figure.dpi'] = curr_dpi


XWindows version:

#!/usr/bin/python

import Xlib
import Xlib.display

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

Another version using 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)

Expanding on @user2366975's answer, to get the current screen size in a multi-screen setup using Tkinter (code in 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

(Should work cross-platform, tested on Linux only)


And for completeness, Mac OS X

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

will give you a list of tuples containing all screen sizes (if multiple monitors present)


I created a PyPI module for this reason:

pip install screeninfo

The code:

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

Result:

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

It supports multi monitor environments. Its goal is to be cross platform; for now it supports Cygwin and X11 but pull requests are totally welcome.


Using Linux, the simplest way is to execute bash command

xrandr | grep '*'

and parse its output using regexp.

Also you can do it through PyGame: http://www.daniweb.com/forums/thread54881.html


In case you have PyQt4 installed, try the following code:

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))

For PyQt5, the following will work:

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))

You could use PyMouse. To get the screen size just use the screen_size() attribute:

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

a will return a tuple, (X, Y), where X is the horizontal position and Y is the vertical position.

Link to function in documentation.


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to screen

How to make flutter app responsive according to different screen size? Unable to capture screenshot. Prevented by security policy. Galaxy S6. Android 6.0 Clear screen in shell How to detect iPhone 5 (widescreen devices)? How to develop or migrate apps for iPhone 5 screen resolution? Android splash screen image sizes to fit all devices How to support different screen size in android Finish all previous activities Android screen size HDPI, LDPI, MDPI How to get the screen width and height in iOS?

Examples related to resolution

Image resolution for new iPhone 6 and 6+, @3x support added? Converting pixels to dp Hide div if screen is smaller than a certain width How can I get screen resolution in java? Set background image according to screen resolution How do I get monitor resolution in Python? Getting the screen resolution using PHP jQuery Screen Resolution Height Adjustment Recommended website resolution (width and height)?