Matrix — une classe du SDK Android (android.graphics.Matrix) représentant une transformation affine via une matrice 3×3. Elle est utilisée pour transformer des objets graphiques — déplacement, mise à l’échelle, rotation et inclinaison. Selon la Documentation pour Développeurs Android (2026), Matrix est l’outil principal pour travailler avec les transformations dans Canvas, Bitmap et Drawable, offrant un contrôle précis des coordonnées lors du rendu personnalisé.
Points Clés
Matrix (android.graphics.Matrix) — une classe du SDK Android représentant une matrice mathématique 3×3 utilisée pour transformer des coordonnées bidimensionnelles. Matrix est le bloc de construction fondamental pour toutes les transformations graphiques dans Android — du déplacement et de la mise à l’échelle de Canvas aux distorsions de perspective complexes de Bitmap.
Contrairement à iOS, qui utilise des structures séparées CGAffineTransform (affine) et CATransform3D (3D), Android combine les transformations affines et de perspective dans une seule classe Matrix. La matrice 3×3 permet de représenter à la fois les opérations affines standard (dernière ligne [0, 0, 1]) et les distorsions de perspective où la dernière ligne contient des valeurs arbitraires. Cela offre plus de flexibilité, mais nécessite une compréhension des mathématiques matricielles.
Matrix est étroitement intégrée à l’API Canvas. Lorsqu’un développeur appelle canvas.translate(), canvas.scale() ou canvas.rotate(), ces méthodes modifient en interne la matrice du contexte graphique. Vous pouvez obtenir la matrice actuelle de Canvas via canvas.getMatrix() et appliquer manuellement une matrice personnalisée avec canvas.setMatrix() ou canvas.concat().
Matrix prend en charge quatre types de base de transformations affines : translate, scale, rotate, skew (incliner). Chaque type a des méthodes pour la pré-multiplication (pre), la post-multiplication (post) et la définition (set). La différence entre preTranslate et postTranslate réside dans l’ordre de multiplication des matrices, ce qui affecte la transformation finale lors de la combinaison d’opérations.
| Opération | Méthode | Paramètres | Description |
|---|---|---|---|
| Déplacer | setTranslate / preTranslate / postTranslate | dx, dy | Déplacement le long des axes X et Y |
| Mettre à l’échelle | setScale / preScale / postScale | sx, sy, px, py | Mise à l’échelle avec point de pivot |
| Pivoter | setRotate / preRotate / postRotate | degrees, px, py | Rotation autour du point de pivot |
| Incliner | setSkew / preSkew / postSkew | kx, ky | Inclinaison (cisaillement) le long des axes |
Translate modifie la position de tous les points par un décalage dx, dy. Un dx positif déplace vers la droite, dy — vers le bas (dans le système de coordonnées d’écran Android, l’axe Y pointe vers le bas). Translate ne modifie pas la forme de l’objet — seulement sa position. C’est l’opération la plus simple et la plus utilisée pour positionner des éléments.
Scale modifie la taille d’un objet avec les facteurs sx (le long de X) et sy (le long de Y). Les paramètres px, py spécifient le point de pivot pour la mise à l’échelle. Si px, py ne sont pas spécifiés, la mise à l’échelle est effectuée par rapport à l’origine (0, 0). Quand sx = sy, l’objet est mis à l’échelle uniformément. Les valeurs négatives créent un reflet.
Rotate fait pivoter un objet d’un angle donné (en degrés) autour d’un point de pivot (px, py). Les degrés positifs correspondent à une rotation dans le sens horaire (contrairement à iOS/macOS, où un angle positif est antihoraire). Si px, py ne sont pas définis, la rotation est effectuée autour de l’origine.
Skew (cisaillement) déforme un objet en l’inclinant le long de l’axe X (kx) ou de l’axe Y (ky). Une valeur de 1,0 incline à 45 degrés. Skew est utilisé pour créer des effets d’inclinaison, des apparences pseudo-3D et des distorsions de perspective.
Matrix stocke ses éléments 3×3 dans un tableau interne de 9 valeurs à virgule flottante (float[9]). L’ordre de stockage est column-major (par colonnes), conforme à la représentation mathématique standard. L’accès aux éléments individuels se fait via des constantes : Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X et ainsi de suite.
La matrice est organisée comme suit : les deux premières colonnes (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) gèrent la mise à l’échelle, la rotation et l’inclinaison. La troisième colonne (MTRANS_X, MTRANS_Y, MPERSP_2) gère la translation et la perspective. Pour les transformations affines, MPERSP_0 et MPERSP_1 sont 0, et MPERSP_2 est 1.
Pour obtenir les valeurs de la matrice, utilisez getValues(float[] values), qui remplit un tableau de 9 éléments. Pour les définir, utilisez setValues(float[] values). Cela permet la manipulation directe de la matrice pour des transformations personnalisées complexes au-delà des méthodes standard translate, scale, rotate et skew.
Matrix fournit plusieurs méthodes pour classer l’état actuel. isIdentity() vérifie si la matrice est une matrice identité. isAffine() vérifie si elle contient uniquement des transformations affines (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Ces vérifications sont utiles pour l’optimisation : si la matrice est identité, la transformation peut être ignorée.
Matrix prend en charge plusieurs catégories d’opérations : définition (set), pré-multiplication (pre), post-multiplication (post), concaténation (concat), inversion (invert) et mappage (map). Chaque catégorie a son objectif lors de la construction de transformations complexes.
preTranslate multiplie la matrice actuelle à gauche par la matrice de translation : result = translate × current. postTranslate multiplie à droite : result = current × translate. La différence réside dans l’ordre d’application : les opérations pre sont appliquées avant les transformations actuelles, les opérations post après. Il en va de même pour preScale, postScale, preRotate, postRotate et preSkew, postSkew.
invert(Matrix inverse) calcule la matrice inverse. Si la matrice originale est singulière (déterminant est zéro), elle retourne faux. concat(Matrix other) multiplie la matrice actuelle par celle fournie : set = set × other. Pour l’ordre inverse, utilisez setConcat(other, this).
mapRect(RectF rect) transforme un rectangle et retourne le résultat dans un nouveau RectF. mapPoints(float[] dst, float[] src) transforme un tableau de points. mapVectors(float[] dst, float[] src) transforme des vecteurs — sans tenir compte de la translation. mapRect est utile pour calculer les boîtes englobantes après transformation.
Matrix est activement utilisée dans deux scénarios clés des graphiques Android : la transformation de Canvas et la transformation de Bitmap. Dans les deux cas, Matrix détermine comment la sortie graphique sera modifiée.
Canvas fournit canvas.setMatrix(matrix) pour le remplacement complet de la matrice actuelle et canvas.concat(matrix) pour multiplier la transformation actuelle par celle fournie. Après avoir appliqué Matrix, tout le rendu suivant — appels drawBitmap, drawRect, drawPath — est effectué dans le système de coordonnées transformé. Canvas maintient également sa propre pile d’états sauvegardés via save() et restore().
Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) crée un nouveau Bitmap avec la transformation fournie appliquée. C’est un outil puissant pour créer des copies mises à l’échelle, pivotées ou déformées d’images sans perdre le Bitmap original. Le paramètre filter contrôle l’anticrénelage lors de l’interpolation des pixels.
setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — une capacité unique de Matrix sans équivalent direct dans CGAffineTransform. Elle calcule une matrice qui transforme des points donnés d’un polygone à un autre. Avec pointCount = 4, une transformation de perspective (projective) complète est créée, permettant de superposer un Bitmap avec distorsion de perspective.
Examinons des exemples pratiques d’utilisation de Matrix pour la transformation graphique dans une application Android avec Kotlin.
L’exemple crée une Matrix pour une transformation combinée : translation de (100, 50), mise à l’échelle de 1,5x et rotation de 45 degrés. L’utilisation de postTranslate après preRotate et preScale modifie l’ordre d’application des opérations.
val matrix = Matrix()
matrix.preScale(1.5f, 1.5f)
matrix.preRotate(45f)
matrix.postTranslate(100f, 50f)
// Application aux points
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)
// Application au rectangle
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)
L’exemple démontre l’application de Matrix à Canvas dans onDraw pour faire pivoter et mettre à l’échelle un cercle autour de son centre. Sauvegarder et restaurer l’état de Canvas garantit que la transformation n’affecte pas les éléments de dessin suivants.
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = 100f
canvas.save()
val matrix = Matrix()
matrix.postTranslate(cx, cy)
matrix.postRotate(30f)
matrix.postScale(1.2f, 1.2f)
canvas.concat(matrix)
val paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
canvas.drawCircle(0f, 0f, radius, paint)
canvas.restore()
}
L’exemple utilise setPolyToPoly pour créer une distorsion de perspective d’un Bitmap. Quatre points source (coins du rectangle original) sont mappés sur quatre points cibles formant un trapèze. Le résultat est un effet d’image inclinée dans l’espace.
fun applyPerspective(
bitmap: Bitmap,
skew: Float
): Bitmap {
val w = bitmap.width.toFloat()
val h = bitmap.height.toFloat()
val src = floatArrayOf(0f, 0f, w, 0f,
0f, h, w, h)
val dst = floatArrayOf(skew, 0f, w - skew, 0f,
0f, h, w, h)
val matrix = Matrix()
matrix.setPolyToPoly(src, 0, dst, 0, 4)
return Bitmap.createBitmap(
bitmap, 0, 0,
w.toInt(), h.toInt(),
matrix, true
)
}
Foire Aux Questions
Matrix travaille avec des transformations affines et de perspective bidimensionnelles via une seule matrice 3×3. Camera (android.graphics.Camera) est une classe de plus haut niveau qui simule une caméra tridimensionnelle : elle crée une rotation 3D et projette ensuite le résultat dans une Matrix 2D. Camera utilise Matrix en interne.
Créez une Matrix avec postRotate(90f) et passez-la à Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Notez qu’en tournant de 90 degrés, la largeur et la hauteur du résultat s’inversent. Pour une rotation d’un angle arbitraire, un recadrage peut être nécessaire pour éviter les zones vides.
Utilisez matrix.invert(resultMatrix). La méthode retourne vrai si l’inversion réussit et écrit la matrice inverse dans resultMatrix. L’inversion peut être impossible si la matrice est singulière (par exemple, avec une échelle nulle). Vérifiez toujours la valeur de retour.
pre multiplie la nouvelle transformation à gauche : result = operation × current — l’opération est appliquée avant les actuelles. post multiplie à droite : result = current × operation — l’opération est appliquée après. Pour une séquence preRotate + postTranslate : d’abord rotation, puis translation.
Oui, Matrix est utilisée dans Jetpack Compose via la classe android.graphics.Matrix en interaction avec Canvas Compose. Dans Compose, graphicsLayer est disponible pour les transformations (scale, rotationX, translationX et autres), mais pour les transformations complexes de Bitmap, Matrix est utilisée dans le code drawWithContent ou drawBehind.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi