Guide des Coordonnées PyAutoGUI : size(), Multi-Écrans, Corrections DPI
Ce que PyAutoGUI verrait sur votre ecran :
pyautogui.size() renvoie les dimensions de votre écran, pyautogui.position() donne la position actuelle de la souris, et pyautogui.click(960, 540) clique au centre d'un écran 1920×1080 — mais seulement quand la mise à l'échelle DPI est désactivée. Si vous avez écrit pyautogui.click(960, 540) et que le clic a atterri ailleurs, ou que pyautogui.locateOnScreen() renvoie de mauvaises coordonnées, vous rencontrez le bug de coordonnées PyAutoGUI le plus courant. Ci-dessous : comment pyautogui.size() fonctionne, les plages multi-écrans, et la solution complète de mise à l'échelle DPI.Screen() renvoie de mauvaises coordonnees. Ou votre capture d'ecran enregistre la mauvaise zone. Ca vous dit quelque chose ?
Ce sont les trois bugs classiques de coordonnees PyAutoGUI, et ils partagent une cause racine : la mise a l'echelle DPI + les coordonnees de l'ecran virtuel multi-ecrans. Nous traitons les trois ci-dessous — avec du code que vous pouvez copier-coller directement dans votre projet. Les valeurs de votre ecran sont detectees ci-dessus.
Ouvrir l'outil gratuit de coordonnees d'ecranLes trois bugs de coordonnees PyAutoGUI
Les problemes de coordonnees PyAutoGUI se repartissent presque toujours dans l'une de ces trois categories :
- Decalage de clic sur les ecrans haute densite :
pyautogui.click(960, 540)n'atterrit pas ou vous l'attendez parce que PyAutoGUI utilise des coordonnees logiques tandis que l'application cible utilise des coordonnees physiques. Traite dans notre guide Mise a l'echelle DPI. - Mauvaise taille d'ecran signalee :
pyautogui.size()renvoie 2560×1440 sur votre ecran 4K parce que Windows lui fournit la resolution logique (mise a l'echelle). Vos scripts calculent de mauvais points centraux, de mauvais pourcentages, de mauvais tout. - Decalage de region de capture :
pyautogui.screenshot(region=(x, y, w, h))capture une zone differente de celle que vous avez specifiee, car les coordonnees de region sont dans l'espace logique mais la capture utilise le tampon de pixels physiques.
Les trois bugs ont la meme cause racine : PyAutoGUI s'execute en tant que processus non sensible au DPI sous Windows par defaut. Le systeme lui fournit des coordonnees logiques. La solution est toujours la meme — le rendre sensible au DPI.
pyautogui.size() vs votre vraie resolution
Que renvoie reellement pyautogui.size() sur un ecran 4K ? Ca depend de votre mise a l'echelle :
| Resolution physique | Mise a l'echelle Windows | pyautogui.size() renvoie | Pixels manquants |
|---|---|---|---|
| 3840×2160 | 100 % | 3840×2160 ✓ | Aucun |
| 3840×2160 | 125 % | 3072×1728 | 768×432 pixels d'ecart |
| 3840×2160 | 150 % | 2560×1440 | 1280×720 pixels d'ecart |
| 3840×2160 | 200 % | 1920×1080 | 1920×1080 pixels d'ecart |
| 2560×1440 | 125 % | 2048×1152 | 512×288 pixels d'ecart |
| 2560×1440 | 150 % | 1707×960 | 853×480 pixels d'ecart |
A 150 % de mise a l'echelle en 4K, PyAutoGUI pense que votre ecran ne fait que 2560 pixels de large. Quand vous cliquez la ou il pense etre le centre (1280, 720), Windows traduit cela en pixel physique (1920, 1080) — qui se trouve etre le vrai centre. Mais toute autre position sera decalée du facteur de mise a l'echelle.
Le correctif complet : configuration PyAutoGUI sensible au DPI
Placez ceci en haut de votre script — avant d'importer PyAutoGUI :
import ctypes
import sys
# Correctif #1 : indiquer a Windows qu'on veut les vrais pixels physiques
if sys.platform == 'win32':
try:
# Sensibilisation DPI par moniteur (ideal pour le multi-ecran)
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except Exception:
# Solution de secours : sensibilisation DPI systeme
ctypes.windll.user32.SetProcessDPIAware()
# MAINTENANT importer PyAutoGUI — il verra les vrais pixels
import pyautogui
# Verifier que le correctif fonctionne
w, h = pyautogui.size()
print(f"Taille d'ecran : {w}x{h}")
# Sur un ecran 4K a 150 %, cela devrait maintenant afficher 3840x2160
Pourquoi SetProcessDpiAwareness(2) plutot que SetProcessDPIAware() ?
| Appel | Niveau | Multi-ecran | Quand l'utiliser |
|---|---|---|---|
SetProcessDPIAware() | Systeme | Utilise le DPI du moniteur principal pour tous les moniteurs | Moniteur unique uniquement |
SetProcessDpiAwareness(2) | Par moniteur | Chaque moniteur signale sa vraie resolution physique | Toute configuration (recommande) |
Si vous avez un ecran de portable 4K a 150 % et un moniteur externe 1080p a 100 %, SetProcessDpiAwareness(2) garantit que PyAutoGUI voit 3840×2160 sur l'ecran du portable et 1920×1080 sur l'externe — les vraies valeurs pour chaque affichage. Pour en savoir plus sur le fonctionnement des coordonnees sur differents moniteurs, consultez notre guide Coordonnees multi-ecrans.
Corriger les decalages de region de capture
Le probleme de region de capture est sournois. Sans le correctif DPI, le parametre region utilise des coordonnees logiques — voila ce qui se passe (l'exemple suppose 150 % de mise a l'echelle sur un ecran 4K ; votre DPR detecte peut etre differer) :
# SANS le correctif (150 % de mise a l'echelle en 4K) :
# Vous voulez capturer les 960x540 pixels en haut a gauche
img = pyautogui.screenshot(region=(0, 0, 960, 540))
# Mais cela capture en fait les 960x540 logiques en haut a gauche
# ce qui correspond a la zone physique (0, 0, 1440, 810) — bien plus que prevu
# AVEC SetProcessDpiAwareness(2) :
# Maintenant la region utilise correctement les pixels physiques
img = pyautogui.screenshot(region=(0, 0, 960, 540))
# Capture exactement les 960x540 pixels physiques en haut a gauche ✓
Important : Apres avoir active la sensibilisation DPI, pyautogui.screenshot() renvoie une image a la pleine resolution physique. Sur un ecran 4K, c'est une image de 3840×2160, pas 2560×1440. Si vous recadriez vos captures avant le correctif, vous devez mettre a jour vos coordonnees de recadrage en pixels physiques.
Multi-ecran : les coordonnees de l'ecran virtuel expliquees
Sur une configuration multi-ecrans, PyAutoGUI travaille avec un seul ecran virtuel qui s'etend sur tous vos moniteurs. Le moniteur principal commence a (0, 0). Les autres s'etendent a partir de la :
- Un moniteur a droite de votre principal commence a X =
largeur_principale(en supposant que les deux moniteurs utilisent la meme mise a l'echelle DPI — les configurations avec DPI mixte sont plus delicates) - Un moniteur a gauche de votre principal a des coordonnees X negatives (par ex. −1920 a −1)
- Un moniteur au-dessus de votre principal a des coordonnees Y negatives
# Verifier la taille de votre ecran virtuel
import ctypes
import pyautogui
# Apres le correctif DPI :
print(pyautogui.size()) # Taille du moniteur principal
x, y = pyautogui.position()
print(f"Position actuelle de la souris : ({x}, {y})")
# Des valeurs negatives signifient que vous etes sur un moniteur a gauche/au-dessus
Pour les formules completes de calcul du centre, des decalages et des positions de bord de n'importe quel moniteur, consultez notre guide Coordonnees multi-ecrans.
Pourquoi locateOnScreen() renvoie de mauvaises coordonnees
pyautogui.locateOnScreen('button.png') est l'une des fonctions les plus utiles de PyAutoGUI — et l'une des plus cassees sur les ecrans haute densite. Le probleme (l'exemple suppose 150 % de mise a l'echelle sur un ecran 4K) :
- Vous faites une capture d'ecran d'un bouton sur votre ecran 4K (l'image fait 3840×2160 pixels physiques)
- Vous decadrez le bouton et l'enregistrez comme
button.png locateOnScreen()effectue une capture — mais sans sensibilisation DPI, Windows renvoie une image a la taille logique (2560×1440) qui a ete re-echantillonnee et floutee par le systeme (virtualisation DPI). Les pixels ne correspondent plus exactement a votre image de reference.- Il essaie de trouver votre bouton net et decoupe en 4K dans cette capture floue et sous-echantillonnee — et echoue ou renvoie de mauvaises coordonnees
La solution : Apres avoir appele SetProcessDpiAwareness(2), les captures internes de PyAutoGUI enregistrent les pixels physiques bruts sans re-echantillonnage par le systeme. Votre image de reference et la capture de recherche sont maintenant a la meme resolution et nettete, donc locateOnScreen() fonctionne correctement.
Astuce : Creez toujours vos images de reference apres avoir active la sensibilisation DPI. Si vous les avez capturees avant le correctif, elles sont en resolution logique et ne correspondront pas aux captures en pixels physiques.
Script cle en main
Copiez-collez ceci dans votre projet. Il gere la sensibilisation DPI, la detection multi-ecran et vous fournit des fonctions utilitaires pour des clics independants de la resolution :
"""
Configuration PyAutoGUI sensible au DPI — a placer en haut de tout script.
Fonctionne sur Windows, macOS et Linux. Compatible multi-ecran.
IMPORTANT : la sensibilisation DPI DOIT etre definie avant d'importer pyautogui,
sinon il met en cache la resolution logique a l'import.
"""
import ctypes
import sys
# --- Definir la sensibilisation DPI AVANT d'importer pyautogui ---
if sys.platform == 'win32':
try:
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except Exception:
try:
ctypes.windll.user32.SetProcessDPIAware()
except Exception:
pass
# MAINTENANT il est sur d'importer pyautogui
import pyautogui
def get_screen_info():
"""Renvoie des informations utiles sur l'ecran."""
w, h = pyautogui.size()
return {
'width': w,
'height': h,
'center': (w // 2, h // 2),
'total_pixels': w * h,
}
def click_relative(x_pct, y_pct):
"""Clique a un pourcentage de la taille de l'ecran (0.0 a 1.0).
Independant de la resolution — fonctionne sur tout ecran."""
w, h = pyautogui.size()
pyautogui.click(int(w * x_pct), int(h * y_pct))
# --- Utilisation ---
info = get_screen_info()
print(f"Ecran principal : {info['width']}x{info['height']}")
print(f"Centre : {info['center']}")
# Exemple : cliquer au centre de l'ecran
click_relative(0.5, 0.5)
Questions frequentes
Ce correctif fonctionne-t-il sur macOS et Linux ?
SetProcessDpiAwareness() n'existe que sur Windows. Sur macOS, PyAutoGUI gere assez bien la mise a l'echelle Retina tout seul. Sur Linux, cela depend de votre serveur d'affichage (X11 vs Wayland). La fonction setup_dpi_awareness() ci-dessus peut etre appelee sans risque partout — elle ne fait simplement rien sur les systemes non-Windows.
Pourquoi mon script fonctionne dans IDLE mais pas en execution directe ?
Certains IDE — y compris IDLE — sont deja sensibles au DPI. Executez votre script dans l'un d'eux et il herite de ce contexte. Lancez le meme script depuis la ligne de commande ou le Planificateur de taches et il demarre en tant que processus non sensible au DPI. Appelez toujours SetProcessDpiAwareness(2) quel que soit le mode de lancement.
Puis-je utiliser PyAutoGUI et OpenCV ensemble ?
Oui. Apres avoir active la sensibilisation DPI, pyautogui.screenshot() renvoie une image PIL en pleine resolution. Vous pouvez la convertir en tableau NumPy pour un traitement OpenCV. Les coordonnees de cv2.matchTemplate() correspondront alors a l'espace de coordonnees en pixels physiques de PyAutoGUI.
Que faire si SetProcessDpiAwareness(2) leve une erreur ?
Elle peut echouer si votre processus a deja ete marque comme non sensible au DPI (par ex., Python a ete lance par un processus parent non sensible au DPI). La solution de secours est SetProcessDPIAware(). Si meme cela echoue, vous etes probablement dans un contexte ou la sensibilisation DPI est heritee du parent — verifiez les parametres de votre lanceur Python ou de votre terminal.
Comment obtenir mes coordonnees de souris pour verifier le correctif ?
Executez print(pyautogui.position()) apres avoir appele setup_dpi_awareness(). Deplacez votre souris dans le coin inferieur droit de votre ecran — la valeur devrait etre proche de (largeur-1, hauteur-1) ou largeur/hauteur sont la resolution physique. Ou utilisez notre outil en ligne de coordonnees d'ecran pour voir votre position en temps reel.
Associe : Coordonnees avant votre script PyAutoGUI ? Voir notre guide de coordonnees.
Associe : Capturer des cibles ? Notre detectedeur enregistre les coordonnees pour PyAutoGUI.