Cette page explique comment effectuer la rotation d'une image avec ImageMagick et y découper la plus grande image rectangulaire possible, tout en maintenant le même format.
Voici une photographie typique qui nécessite cette opération : la scène s'est présentée si vite que j'ai à peine eu le temps de déclencher et absolument aucun pour peaufiner le cadrage. L'image penche !
On souhaite donc tourner cette image de 6 degrés dans le sens des aiguilles d'une montre, pour obtenir au final :
La commande suivante d'ImageMagick exécute toute la procédure :
magick input.jpg -set option:origw %w -set option:origh %h -set option:neww "%[fx:origh*origw/(origh*abs(cos(6*pi/180)) + origw*abs(sin(6*pi/180)))]" -rotate 6 -gravity center -extent %[neww]x%[fx:neww*origh/origw] output.jpg
input.jpg est le nom du fichier d'entrée.
-set option:origw %w et -set option:origh %h stockent dans les variables origw et origh la largeur et la hauteur de l'image originelle.
-set option:neww "%[fx:origh*origw/(origh*abs(cos(6*pi/180)) + origw*abs(sin(6*pi/180)))]"calcule la largeur de l'image finale et stocke le résultat dans la variable
neww. On aura besoin des valeurs de ces variables dans la suite.
-rotate 6 effectue la rotation de 6 degrés dans le sens des aiguilles d'une montre. À ce stade, l'image transformée est :
Les côtés sont devenus obliques. Il faut donc maintenant découper à l'intérieur de cette nouvelle image, un rectangle dont les côtés sont horizontaux et verticaux, le plus grand possible, et qui conserve le rapport entre longueur et largeur de l'image d'origine (ici 3:2), c'est-à-dire la zone claire ci-dessous :
On réalise cette opération avec les deux arguments suivants :
-gravity center indique à ImageMagick que les arguments suivants sont pris à partir du centre de l'image.
-extent %[neww]x%[fx:neww*origh/origw] découpe un rectangle dans l'image (celle déjà tournée), à partir du centre, dont la largeur est la variable neww calculée auparavant, et dont la hauteur est calculée selon le rapport des dimensions de l'image originelle.
output.jpg est le nom du fichier de sortie, la Version corrigée vue plus haut.ABCD est le rectangle (en vert) de l'image originelle; A'B'C'D' est le rectangle (bleu) tourné de α degrés dans le sens des aiguilles d'une montre; MPQR est le rectangle (rouge) de l'image finale voulue. Sa largeur est MP et on a :
MP = AD x AB/(AD x |cos α| + AB x |sin α|)
Les calculs mathématiques pour retrouver ce résultat se trouve plus bas.
Sur une station de travail Unix, cette façon de faire permet de corriger tout type d'images avec la ligne de commande.
On peut aussi l'utiliser sur les téléphones Android, une fois installés l'émulateur de terminal et système de paquets termux, puis ImageMagick bien sûr. Avec en plus dcraw, on peut aussi "dérawtiser" les fichiers RAW des appareils photos numériques et faire tout le traitement photographique sur le téléphone. Installer exiftool et dialog permet enfin de pouvoir construire des interfaces complètes CLI pour faire sur le téléphone, relativement convivialement, toute sorte de traitements d'image.
Tous les logiciels cités dans cette page sont évidemment libres et open-source.
MP = AD x AB/(AD x |cos α| + AB x |sin α|)
On se place dans le repère de centre O, centre de ABCD. Les coordonnées de A' s'obtiennent par le produit de la matrice de la rotation de centre O et d'angle -α et des coordonnées de A. Idem pour celles de B'. La largeur MP est deux fois l'abscisse du point d'intersection M des droites (OA) et (A'B') (ou (OD) et (C'D'); cela dépend de l'angle α). On écrit les équations réduites des droites (OA) et (A'B') et on cherche les coordonnées de M. Remarque : le sens de rotation positif pour ImageMagick est celui des aiguilles d'une montre.
On note w=AB, h=AD, w'=A'B' et h'=A'D'. Alors :
x_A=w/2 et y_A=h/2
x_B=-w/2 et y_B=h/2.
On en déduit l'équation réduite de (OA) : y=x h/w.
⎧x_A'⎫ ⎧ cos(-α) -sin(-α) ⎫⎧x_A⎫ | |=| || | ⎩y_A'⎭ ⎩ sin(-α) cos(-α) ⎭⎩y_A⎭
⎧x_B'⎫ ⎧ cos(-α) -sin(-α) ⎫⎧x_B⎫ | |=| || | ⎩y_B'⎭ ⎩ sin(-α) cos(-α) ⎭⎩y_B⎭
On en déduit l'équation réduite de (A'B') : y=-x tan α + h/(2 cos α).
Puis les coordonnées de l'intersection M :
x_M=hw/(2h cos α + 2w sin α)
y_M=x_M w/h.
Et enfin :
w'=hw/(h cos α + w sin α)
h'=w' h/w.
L'ajout des valeurs absolues dans la formule permet de tenir compte des cas où l'intersection cherchée est celle entre (OD) et (C'D') et où l'angle α est compris entre 90° et 370°.
Articles (313)
Je préfère vraiment les contacts à l'ancienne, par courrier électronique à l’adresse jpsmail(at)free.fr. Antispam : penseras-tu à remplacer (at) par @ dans l’adresse ? Que cela ne t'enpêche pas d'ajouter un commentaire :