logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 11-07-2020 21:14:40

Debeee
Membre
Distrib. : Bullseye 64
Noyau : 5.10.0-10
(G)UI : mate
Inscription : 11-02-2015

Portable + écran externe : réglages de la luminosité et calibration

Bonjour à tou(te)s,

tout est parti du besoin suivant : connecter mon ordi portable (11") rapidement sur un écran externe et pouvoir régler la luminosité de cet écran.
Accessoirement, depuis pas mal de temps, je cherche une solution simple pour appliquer des profils icc à mes écrans.
Un petit script a permis de répondre à ces besoins.

La connection du portable sur l'écran externe est pénible : outre la connection physique, il faut aller dans le tableau de bord "affichage" et faire plusieurs manips pour avoir un affichage correct. Le script permet d'allumer le 2e en éteignant le 1e et vice versa, ceci avec une seule combinaison de touches (bascule) : très pratique.

Ensuite, mon écran externe est bloqué à la luminosité maxi, et pas moyen de le régler (touches du portable inopérantes et menu de l'écran verrouillé (?)) : le script permet de régler la luminosité avec 2 combinaisons de touches.

Enfin, la calibration des écrans. Ce que je propose ici est une solution de "pauvre". Il existe une bonne solution (DisplayCal) pour calibrer ses écrans à l'aide d'une sonde et charger divers profils, mais c'est assez laborieux en utilisation courante. Et je n'ai pas de sonde.
J'ai récupéré des profils icc qui "marchent" plutôt pas mal sur mes moniteurs, le but est de les charger avec juste une combinaison de touches. En fait, le script va balayer plusieurs profils (ou pas de profil) de manière circulaire à chaque pression des touches. Par exemple, avec un profil opti et pas de profil, on va basculer alternativement de l'un à l'autre avec la même combinaison de touches. Avec 3 réglages, on balaye les 3 et on revient au 1e. But : on peut avoir des profils assez différents : par exemple, un "pêchu", un "subtil", et pourquoi pas un 3e profil volontairement jaune pour travailler sur du texte sans se casser les yeux avec de la lumière trop bleue => inutile d'acheter des lunettes à filtre jaune smile
Un gros avantage de cette solution est que si vous regardez des photos plein écran, vous pouvez passer en revue vos profils et choisir le plus plaisant sans manip compliquée.
Cerise sur le gâteau, ces profils sont complétés par un réglage fin du gamma sur les 3 canaux RVB. Il y a donc moyen d'avoir un moniteur "propre" à pas cher. Personnellement, j'ai bien amélioré mes écrans, et je peux enfin regarder des photos dessus sans que ça me pique les yeux, et même avec plaisir !

Je vais donc vous présenter le script qui sert dans les conditions restrictives suivantes :
- un ordi portable connecté à un écran externe (1 seul à la fois, mais on peut connecter différents moniteurs externes)
- un seul des deux écrans est allumé : soit le portable, soit l'externe, pas les deux
- ce script a des fonctionnalités simples destinées à être pilotées par raccourcis clavier

les fonctionnalités sont les suivantes :
- bascule entre les deux écrans
- réglage de la luminosité de l'écran externe
- calibration différenciée des deux moniteurs (un seul à la fois !)
- la calibration des couleurs fonctionne aussi avec le portable seul, sans moniteur externe, les autres fonctions sont désactivées pour le portable.
- j'avais prévu une option permettant de recharger automatiquement le dernier réglage (profil + gamma) au démarrage de la machine (script dans le dossier de démarrage), mais j'avoue que j'ai été feignasse, donc cette fonctionnalité n'est pas implémentée.

J'avais attaqué ce problème dans ce fil : https://debian-facile.org/viewtopic.php?id=27799
et chemin faisant, malgré l'aide de Croutons (merci Croutons !), comme je n'ai pas trouvé de solution fonctionnelle, j'ai bâti la mienne.

Je n'ai jamais fait de shell et je suis un cancre en ligne de commande : ça partait très mal et donc tout ça m'a demandé pas mal d'investissement !

J'ai puisé la gnose essentiellement sur ces sites :

https://openclassrooms.com/fr/courses/4 … ipts-shell
https://fr.wikibooks.org/wiki/Programma … troduction
https://www.supinfo.com/articles/single … teres-bash

J'ai aussi beaucoup décortiqué le script donné par Croutons (voir le fil d'origine ci-dessus) qui m'a bien aidé à résoudre les pb de syntaxe et donné les idées de base (utilisation de xrandr par ex).
J'en ai bavé, je n'ai pas trouvé de logique cohérente dans la syntaxe du shell, ça m'a beaucoup ralenti.

Mais au final, ça marche !

Le but, c'est que des gens intéressés utilisent ce script tel quel, bien sûr, mais aussi, j'ai volontairement mis pas mal de lignes de commentaires histoire que si ce script ne marche pas sur une config donnée ou que quelqu'un veuille en utiliser juste une ou deux fonctions, ou les modifier, qu'il puisse les modifier (assez) facilement.

Bon, si vous ne dormez pas déjà, on y va.

Voilà le code :


#!/usr/bin/env bash

# version 1.1
# 11/07/2020

################### chemin d'accès fichier config #################

chemin='/home/mon_id/.config/color/icc/devices/display'

########################## fonctions ##############################

# fonction qui donne le nom du moniteur intégré du portable
moni_prin() {
xrandr --verbose | grep -w -m1 'connected' | cut -f1 -d' '
}


# fonction qui donne le nom du moniteur externe (s'il n'y en a au plus qu'un de connecté !)
moni_ext() {

if [[ $(xrandr --verbose | grep -cw  'connected') = 1 ]]
then
    echo 'inexistant'
else
    xrandr --verbose | grep -w  'connected' | tail -1 | cut -f1 -d' '
fi

}


# fonction qui donne le nom du moniteur actif (primary)
moni_actif() {
xrandr --verbose | grep -w 'primary' | cut -f1 -d' '
}


# fonction qui donne la luminosité du moniteur actif
lum() {
xrandr --verbose | grep -w 'primary' -A5 | grep 'Brightness' | cut -f2- -d: | tr -d ' '
}


# fonction qui donne le gamma du moniteur actif (valeur du fichier de profils)
# paramètre d'entrée : variable $chemin

gamma() {
moni1=$(moni_actif)

# nombre de moniteurs répertoriés dans le fichier de calibration
nbre_moni=$(grep 'nbre_moni' "$1/profils.txt" | cut -f2 -d=)

# n° de ligne de calibration du fichier pour le moniteur actif
lig_moni=$(cat "$1/profils.txt" | tail -"$nbre_moni" | grep "$moni1" | cut -f2 -d: | tr -d ' ')

# gamma du moniteur actif
cat "$1/profils.txt" | grep "$moni1" | head -"$lig_moni" | tail -1 | cut -f3- -d:

}

# fonction d'initialisation, mettre le script dans le dossier démarrage pour
# mettre en place le dernier profil utilisé au boot (sur le moniteur principal)
# à faire ...
init_calib() {
exit
}

# fonction d'incrément/décrément de la luminosité  par pas de 0.1
# paramètres d'entrée : '+' ou '-' et variable $chemin
# butées à 0.2 et 1.0

reg_lum() {

inc=$( echo "0.1"  | bc)
lum1=$(lum)

# attention à la syntaxe : bien mettre les espaces "$a" = 'toto', [ "$a, ! [ etc
# le moindre espace qui manque ou en trop et ça ne marche pas (soit erreur, soit pas
# d'erreur mais test faux en sortie. Noter la syntaxe avec double crochet
if  ! [[ $lum1 = '1.0'  &&  $1 = '+' ]] && ! [[ $lum1 = '0.20'  &&  $1 = '-' ]]
then
    lum1=$(echo "$lum1 $1 $inc" | bc)
fi

# envoi des paramètres au moniteur via xrandr
xrandr --output $(moni_actif) --brightness $lum1 --gamma $(gamma $2)

}



# fonction d'échange d'écran interne/externe

chgt_ecran() {

# on teste si l'écran externe est branché
[ "$(moni_ext)" = 'inexistant' ] && exit

# si oui, on swappe
if [ "$(moni_actif)" = "$(moni_prin)" ]
then
    xrandr --output "$(moni_prin)" --off
    xrandr --output "$(moni_ext)" --auto --primary
else
    xrandr --output "$(moni_ext)" --off
    xrandr --output "$(moni_prin)" --auto --primary
fi

}


# fonction de rotation des profils de calibration
# nécessite le fichier des calibrations présent dans le répertoire des profils
# fichier nommé 'profils.txt'
# paramètre d'entrée : variable $chemin

calib_ecran() {

# paramètres d'entrée (moniteur et luminosité)
moni1=$(moni_actif)
lum1=$(lum)


# nombre de lignes du fichier de calibration (profils.txt) situé dans le répertoire des profils
nlig_fich=$(wc -l "$1/profils.txt" | cut -f1 -d' ')

# nombre de moniteurs répertoriés dans le fichier de calibration
nbre_moni=$(grep 'nbre_moni' "$1/profils.txt" | cut -f2 -d=)

# nombre de lignes de calibration du fichier pour le moniteur actif
nlig_moni=$(($(cat "$1/profils.txt" | grep -c "$moni1")-1))

# n° de ligne de calibration du fichier pour le moniteur actif avant changement
lig_moni_a=$(cat "$1/profils.txt" | tail -"$nbre_moni" | grep "$moni1" | cut -f2 -d:)

# n° de ligne de calibration du fichier pour le moniteur actif après changement
# on boucle sur les différentes calibrations relatives au moniteur actif (modulo)
lig_moni_p=$(($(($lig_moni_a%$nlig_moni))+1))

# profil icc du moniteur actif après modification
prof_moni=$(cat "$1/profils.txt" | grep "$moni1" | head -"$lig_moni_p" | tail -1 | cut -f2 -d: | tr -d ' ')

# paramètre à rentrer dans xcalib
[ $prof_moni = 'uncalib' ] && prof_moni='-c' || prof_moni="$1/$prof_moni"

# gamma du moniteur actif après modification
gamma_moni=$(cat "$1/profils.txt" | grep "$moni1" | head -"$lig_moni_p" | tail -1 | cut -f3- -d:)

# nouvelle calibration du moniteur
xrandr --output "$moni1" --gamma "$gamma_moni" --brightness "$lum1"
xcalib  "$prof_moni"

# mise à jour du fichier de config
cp "$1/profils.txt" "$1/profils_temp.txt"
cat "$1/profils_temp.txt" | head -"$(($nlig_fich-$nbre_moni))" > "$1/profils.txt"
cat "$1/profils_temp.txt" | tail -"$nbre_moni" | grep -v "$moni1" >> "$1/profils.txt"
echo "$moni1 : $lig_moni_p" >> "$1/profils.txt"

}



############################# programme principal ###################

# Test des paramètres et aiguillage

case $# in
    0)
        init_calib ;;
    1)
        case $1 in
            [+-])
                [[ "$(moni_actif)" = "$(moni_prin)" ]] && exit || reg_lum $1 $chemin ;;
            e)
                chgt_ecran ;;
            c)
                calib_ecran $chemin ;;
        esac ;;
    *)
        exit ;;
esac
 



J'ai mis tout ça dans un fichier que j'ai appelé "ajustecran" (sans extension) et que j'ai placé (en root) dans le répertoire /usr/local/bin, qui est dans le PATH.
Il faut d'abord rendre ce fichier éxécutable.
Depuis le répertoire "monrep" contenant "ajustecran" :

chmod +x ajustecran
su -


après avoir rentré le mot de passe :

cd monrep
cp ajustecran /usr/local/bin



Dans ce script, vous avez en en-tête un chemin d'accès qu'il faudra modifier.
C'est le chemin d'accès du répertoire qui va contenir vos profils icc, et où vous allez rajouter un fichier de configuration utilisé par le script, qui s'appellera obligatoirement "profils.txt"
Vous mettez ce répertoire où vous voulez, si vous avez déjà des profils icc dans un répertoire, c'est bon, il suffira d'y rajouter le fichier "profils.txt"

Ensuite, vous avez la ribambelle de fonctions, et en dernier, le programme principal qui sert à aiguiller la commande en fonction des paramètres d'entrée.

Normalement, le script ne dépend pas de la config (nous sommes d'accord, dans le strict cadre un portable + un écran externe). J'espère avoir bien fait les choses. Si jamais ça coince chez vous, n'hésitez pas à remonter le pb.

Le fichier de config doit respecter une syntaxe particulière :

nbre_moni=2
eDP-1 : uncalib : 1.0:1.0:1.0
eDP-1 : maison_3.icc : 0.85:0.88:0.85
HDMI-1 : uncalib : 1.0:1.0:1.0
HDMI-1 : maison_3.icc : 0.9:0.95:0.9
eDP-1 : 1
HDMI-1 : 1



La 1e ligne donne le nombre de connecteurs de moniteurs différents à calibrer.
Ici, j'ai eDP-1 (moniteur du portable) et HDMI-1, d'où "nbre_moni=2". J'ai aussi dispo VGA-1 : si je veux l'utiliser, il faut le mentionner, et mettre les profils des moniteurs qui y seront connectés.
Pour avoir la liste de vos moniteurs :

~$ xrandr --verbose | grep 'connected' | cut -f1 -d' '


eDP-1
VGA-1
HDMI-1
DP-1



Ensuite, vous avez, par type de moniteurs, la liste des profils et des corrections de gamma à appliquer. Respectez la syntaxe, avec les espaces, sinon ça ne marchera pas.
ATTENTION : surtout pas d'espaces dans les noms des profils (mettre un _ à la place)
Evidemment, ces noms doivent rigoureusement être les noms des profils situés dans le répertoire.
Pour un moniteur non calibré, mettre 'uncalib' à la place du nom du profil.

Les deux dernières lignes : il faut les initialiser (à 1 c'est bon), une ligne par moniteur : c'est mis à jour par le script et ça donne le n° de ligne du profil chargé par type de moniteur.
ATTENTION : surtout pas de retour chariot après la dernière ligne !!

Voilà, vous pouvez utiliser le tout, depuis n'importe quel répertoire (l'éxécutable est placé dans un répertoire déclaré dans le PATH, donc accessible de partout), avec une syntaxe simplifiée :

- pour basculer d'un écran à l'autre (inactif si le portable n'est pas connecté à un moniteur externe) :

ajustecran e



- pour augmenter la luminosité (écran externe uniquement, inactif sur le portable) :

ajustecran +



- pour diminuer la luminosité (écran externe uniquement, inactif sur le portable) :

ajustecran -



- pour changer le profil couleur (portable seul, ou avec moniteur externe, modification propre à chaque moniteur quand il est actif) :

ajustecran c



[edit] Je vous conseille vivement de tester ce script dans un terminal avant d'affecter les raccourcis clavier, histoire de vérifier que ça marche. Je l'ai installé sur un 2e portable (Debian testing idem le 1er), et je suis tombé sur un bug qui n'en n'est pas un, car il s'agit d'un paquet Debian qui était manquant (le paquet 'bc', qui permet de faire des calculs décimaux en shell => ??). Il suffit de le charger via synaptic par exemple et tout rentre dans l'ordre. Et aussi, attention à la syntaxe des noms de moniteurs dans le fichier "profils.txt" : j'en ai un avec 'VGA-1' et l'autre avec 'VGA1'. Si comme moi vous faites du copier-coller bourrin, ça ne marche pas... [/edit]

Normalement, vous ne pouvez pas faire de boulette, les tests prévoient les mauvaises manips, et invalident les commandes.

Et bien sûr, sous Mate, j'ai assigné des raccourcis claviers à ces 4 options (la commande à rentrer dans le raccourci clavier est la même que ci-dessus), respectivement ctrl+alt+e, ctrl+alt+'+', ctrl+alt+'-', ctrl+alt+c

Sous Mate, par défaut, ctrl+alt+'+' et ctrl+alt+'-' servent à basculer sur le bureau au dessus ou au dessous du bureau actif. J'ai 4 bureaux "en ligne", j'ai désactivé ces commandes pour les récupérer, elles sont pratiques et faciles à mémoriser.

Et voilà...

A la suite de ce (trop) long post, un petit mot sur les calibrations gamma pour ceux que ça intéresse.

Dernière modification par Debeee (12-07-2020 16:15:30)

Hors ligne

#2 11-07-2020 21:15:45

Debeee
Membre
Distrib. : Bullseye 64
Noyau : 5.10.0-10
(G)UI : mate
Inscription : 11-02-2015

Re : Portable + écran externe : réglages de la luminosité et calibration

Les courbes de gamma ont un profil assez particulier.
Pour se faire une très bonne idée, voir l'excellent site d'Arnaud Frich, qui maîtrise très bien la couleur :
https://www.guide-gestion-des-couleurs. … ecran.html
Vous avez le droit de regarder les autres pages de ce site...

Le pb, c'est que les valeurs de gamma rentrées en paramètre dans xrandr n'ont rien à voir avec celles données dans le site ci-dessus (et qui sont les valeurs "officielles" du gamma).
En fait, en entrée, on donne une valeur à xrandr, et en sortie (avec --verbose), on retrouve la même, mais inversée (1/x) !! Et je pense que c'est cette valeur inversée qui correspond au "vrai" gamma.
Si quelqu'un a une info là dessus, je suis preneur.
C'est chelou, il faut le savoir et faire avec.

Une valeur de gamma de 1 correspond à une courbe de réponse entrée/sortie qui est une fonction linéaire, sa représentation est une droite (d'équation y=x, soit sortie = entrée), avec f(0)=0 et f(1)=1 : voir sur le site, aux 2/3 de la page environ, le graphique du paragraphe "courbes de réponse et gamma".

Un gamma plus petit que 1 correspondra à une courbe située au dessus de cette droite. Les tons foncés vont être remontés, mais le contraste sur les ton moyens sera affaibli. Si à la base on a un moniteur très contrasté avec des ombres "enterrées", on pourra le corriger en mettant un gamma plus petit que 1.
Avec xrandr, ça va donner l'inverse, on mettra une valeur supérieure à 1 (molo ! 1.1 ou 1.2 sera une bonne base de départ. Essayez 2 histoire de rigoler !).

Pour commencer, la commande à passer pour avoir la liste de vos moniteurs et leurs paramètres courants :

~$ xrandr --verbose | grep -w 'connected' -A5



eDP-1 connected (normal left inverted right x axis y axis)
  Identifier: 0x42
  Timestamp:  7630390
  Subpixel:   unknown
  Clones:    
  CRTCs:      0 1 2
--
HDMI-1 connected primary 1280x1024+0+0 (0x182) normal (normal left inverted right x axis y axis) 376mm x 301mm
  Identifier: 0x44
  Timestamp:  7630390
  Subpixel:   unknown
  Gamma:      1.1:1.2:1.0
  Brightness: 0.70
 



A noter que les gamma de 1.1, 1.2 et 1 lus en sortie correspondent à des valeurs de 0.95, 0.87 et 1 donnés en entrée pour obtenir ce réglage.

Ensuite, sur le moniteur actif (on va prendre l'ex précédent, HDMI-1) :

~$ xrandr --output HDMI-1 --gamma 1.3:1.3:1.3 -- brightness 0.7



Ne pas oublier la luminosité lue précédemment, sinon elle est mise à 1.0 d'office

Essayez avec plus (allez, 2 !)

Au contraire, si vous avez un moniteur un peu pâle avec pas trop de contraste, il faut donner un "vrai" gamma plus grand que 1 (cf courbes du site) : les ombres seront plus sombres, le contraste dans les tons moyens sera plus fort (la courbe est plus pentue que la droite de la courbe neutre dans cette zone).
On va donc augmenter globalement le contraste. Essayez avec 0.7:0.7:0.7 la commande précédente.

Application, pour des gens mal voyants : on peut booster le contraste au taquet en mettant du 0.5:0.5:0.5 (essayez pour voir). Avec le script, on passe de l'écran normal au surcontrasté  et vice-versa en une combinaison de touche. Et vous réglez le contraste qui vous va.

Maintenant, les corrections de couleur.
Pas dur, on va mettre des valeurs différentes pour chaque canal.
Ecran trop bleu ? on diminue la valeur du bleu. Trop jaune : on augmente le bleu. Etc.
Les valeurs des gamma sont Rouge:Vert:Bleu
Imaginez, votre profil (comme le mien au départ) est trop peu contrasté et un peu jaune/rouge : j'ai mis du 0.85:0.9:0.88 et le tour est joué.
Il faut tâtonner un peu, mais justement, vous pouvez faire plusieurs profils avec le même profil icc mais des gamma différents et les balayer grâce au script avec ctrl+alt+c sur un lot de photos pour voir. L'idéal est de comparer les mêmes photos avec un ordi calibré (un copain bienveillant vous l'a prêté !)

Voilà, vous avez toutes les billes pour peaufiner les réglages de votre écran !
Vous pouvez trouver des profils bien dégrossis pour votre moniteur ici :
https://www.lesnumeriques.com/photo/tel … 00539.html

Hors ligne

Pied de page des forums