Matrix în Android: ce este, tipuri de matrici și lucrul cu transformări

Autor: IT Sectr Publicat: 2026-07-22 Timp de citire: 9 min

Matrix — este o clasă din Android SDK (android.graphics.Matrix) care reprezintă o transformare afină printr-o matrice 3×3. Este utilizată pentru transformarea obiectelor grafice — deplasare, scalare, rotire și înclinare. Conform Android Developers Documentation (2026), Matrix este instrumentul principal pentru lucrul cu transformări în Canvas, Bitmap și Drawable, asigurând controlul precis al coordonatelor la desenarea personalizată.

Principalele puncte

  • Matrix — clasă Android pentru transformări afine și prospective cu matrice 3×3
  • Operații afine: translate (deplasare), scale (scalare), rotate (rotire) și skew (înclinare)
  • Matrix suportă transformări prospective (projective) prin setPolyToPoly
  • Ordinea aplicării operațiilor este importantă — Matrix.concat execută înmulțirea secvențială
  • Matrix se aplică la Canvas, Bitmap, RectF, PointF și Path în grafica Android

Ce este Matrix în Android?

Matrix (android.graphics.Matrix) — este o clasă Android SDK care reprezintă o matrice matematică 3×3 utilizată pentru transformarea coordonatelor bidimensionale. Matrix este elementul de bază pentru toate transformările grafice în Android — de la deplasarea și scalarea Canvas până la distorsiunile complexe de perspectivă ale Bitmap.

Spre deosebire de iOS, unde se utilizează structuri separate CGAffineTransform (afine) și CATransform3D (3D), Android combină transformările afine și prospective într-o singură clasă Matrix. Matricea 3×3 permite reprezentarea atât a operațiilor standard afine (ultimul rând [0, 0, 1]), cât și a distorsiunilor de perspectivă când ultimul rând conține valori arbitrare. Aceasta oferă mai multă flexibilitate, dar necesită înțelegerea matematicii matricelor.

Matrix este strâns integrat cu Canvas API. Când dezvoltatorul apelează canvas.translate(), canvas.scale() sau canvas.rotate(), aceste metode modifică intern matricea contextului grafic. Matricea curentă a Canvas poate fi obținută prin canvas.getMatrix(), iar una personalizată poate fi aplicată manual prin canvas.setMatrix() sau canvas.concat().

Tipuri de transformări Matrix

Matrix suportă patru tipuri de bază de transformări afine: translate, scale, rotate, skew (înclinare). Fiecare tip are metode pentru pre-înmulțire (pre), post-înmulțire (post) și setare (set). Diferența dintre preTranslate și postTranslate constă în ordinea înmulțirii matricelor, ceea ce afectează transformarea finală la combinare.

OperațieMetodăParametriDescriere
TranslatesetTranslate / preTranslate / postTranslatedx, dyDeplasare de-a lungul axelor X și Y
ScalesetScale / preScale / postScalesx, sy, px, pyScalare cu punct de referință
RotatesetRotate / preRotate / postRotatedegrees, px, pyRotire în jurul punctului de referință
SkewsetSkew / preSkew / postSkewkx, kyÎnclinare (deplasare) de-a lungul axelor

Translate — deplasare

Translate modifică poziția tuturor punctelor cu deplasarea dată dx, dy. dx pozitiv deplasează la dreapta, dy — în jos (în sistemul de coordonate al ecranului Android, axa Y este orientată în jos). Translate nu modifică forma obiectului — doar poziția acestuia. Este cea mai simplă și frecvent utilizată operație pentru poziționarea elementelor.

Scale — scalare

Scale modifică dimensiunea obiectului cu coeficienții sx (de-a lungul X) și sy (de-a lungul Y). Parametrii px, py specifică punctul de referință al scalării (pivot point). Dacă px, py nu sunt specificați, scalarea se efectuează relativ la originea coordonatelor (0, 0). La sx = sy, obiectul se scalează uniform. Valorile negative creează o reflexie.

Rotate — rotire

Rotate rotește obiectul cu un unghi dat (în grade) în jurul punctului de referință (px, py). Valoarea pozitivă a gradelor corespunde rotirii în sensul acelor de ceasornic (spre deosebire de iOS/macOS, unde unghiul pozitiv este în sens invers acelor de ceasornic). Dacă px, py nu sunt specificați, rotirea se efectuează în jurul originii coordonatelor.

Skew — înclinare

Skew (deformare) deformează obiectul înclinându-l de-a lungul axei X (kx) sau axei Y (ky). Valoarea 1.0 înclină la 45 de grade. Skew este utilizat pentru a crea efecte de înclinare, simularea unei vederi tridimensionale (pseudo-3D) și distorsionarea perspectivei.

Structura matricei 3×3

Matrix stochează elementele matricei 3×3 într-un tablou intern de 9 valori în virgulă mobilă (float[9]). Ordinea de stocare — column-major (pe coloane), ceea ce corespunde reprezentării matematice standard. Accesul la elemente individuale se face prin constante: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X și așa mai departe.

Elementele matricei

Matricea este organizată astfel: primele două coloane (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) răspund de scalare, rotire și înclinare. A treia coloană (MTRANS_X, MTRANS_Y, MPERSP_2) — pentru deplasare și perspectivă. Pentru transformarea afină, MPERSP_0 și MPERSP_1 sunt egale cu 0, iar MPERSP_2 este egal cu 1.

Pentru obținerea valorilor matricei se utilizează getValues(float[] values), care umple un tablou de 9 elemente. Pentru setare — setValues(float[] values). Acest lucru permite manipularea directă a matricei pentru transformări personalizate complexe care depășesc metodele standard translate, scale, rotate și skew.

Verificarea tipului matricei

Matrix oferă mai multe metode pentru clasificarea stării curente. isIdentity() verifică dacă matricea este unitate. isAffine() — dacă conține doar transformări afine (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Aceste verificări sunt utile pentru optimizare: dacă matricea este unitate, transformarea poate fi omisă.

Operații de bază cu Matrix

Matrix suportă mai multe categorii de operații: setare (set), pre-înmulțire (pre), post-înmulțire (post), concatenare (concat), inversare (invert) și mapare (map). Fiecare categorie își rezolvă sarcina la construirea transformărilor complexe.

Operații Pre și Post

preTranslate înmulțește matricea curentă la stânga cu matricea de deplasare: result = translate × current. postTranslate înmulțește la dreapta: result = current × translate. Diferența constă în ordinea aplicării: operațiile pre se aplică înaintea transformărilor curente, operațiile post — după. Similar funcționează preScale, postScale, preRotate, postRotate și preSkew, postSkew.

Inversare și concatenare

invert(Matrix inverse) calculează matricea inversă. Dacă matricea sursă este degenerată (determinantul este zero), se returnează false. concat(Matrix other) înmulțește matricea curentă cu matricea transmisă: set = set × other. Pentru ordinea inversă, utilizați setConcat(other, this).

Map — aplicarea la puncte și dreptunghiuri

mapRect(RectF rect) transformă dreptunghiul și returnează rezultatul într-un nou RectF. mapPoints(float[] dst, float[] src) transformă un tablou de puncte. mapVectors(float[] dst, float[] src) transformă vectori — fără a lua în considerare deplasarea (translate). mapRect este util pentru calcularea bounding box după transformare.

Aplicarea în Canvas și Bitmap

Matrix este utilizată activ în două scenarii cheie ale graficii Android: transformarea Canvas și transformarea Bitmap. În ambele cazuri, Matrix determină cum va fi modificată ieșirea grafică.

Transformarea Canvas prin Matrix

Canvas oferă metodele canvas.setMatrix(matrix) pentru înlocuirea completă a matricei curente și canvas.concat(matrix) pentru înmulțirea transformării curente cu cea transmisă. După aplicarea Matrix, tot desenul ulterior — apelurile drawBitmap, drawRect, drawPath — se execută în sistemul de coordonate transformat. Canvas păstrează, de asemenea, propria stivă de stări salvate prin save() și restore().

Transformarea Bitmap prin Matrix

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) creează un nou Bitmap cu aplicarea transformării date. Acesta este un instrument puternic pentru crearea de copii scalate, rotite sau deformate ale imaginilor fără a pierde Bitmap-ul original. Parametrul filter controlează netezirea la interpolarea pixelilor.

setPolyToPoly — transformări prospective

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — o capacitate unică a Matrix, fără analog direct în CGAffineTransform. Calculează matricea care transformă punctele date dintr-un poligon în altul. La pointCount = 4, se creează o transformare prospectivă (projective) completă, permițând aplicarea Bitmap cu distorsiune de perspectivă.

Exemple de cod în Kotlin

Să examinăm exemple practice de utilizare a Matrix pentru transformarea graficii într-o aplicație Android în Kotlin.

Transformări afine de bază

Exemplul creează o Matrix pentru o transformare combinată: deplasare cu (100, 50), scalare de 1.5 ori și rotire de 45 de grade. Utilizarea postTranslate după preRotate și preScale schimbă ordinea aplicării operațiilor.

kotlin
val matrix = Matrix()
matrix.preScale(1.5f, 1.5f)
matrix.preRotate(45f)
matrix.postTranslate(100f, 50f)

// Aplicare la puncte
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// Aplicare la dreptunghi
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

Transformarea Canvas cu save și restore

Exemplul demonstrează aplicarea Matrix la Canvas în onDraw pentru rotirea și scalarea unui cerc în jurul centrului său. Salvarea și restaurarea stării Canvas garantează că transformarea nu va afecta elementele de desen ulterioare.

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

Distorsionarea perspectivei prin setPolyToPoly

Exemplul utilizează setPolyToPoly pentru a crea o distorsionare de perspectivă a Bitmap. Patru puncte sursă (colțurile dreptunghiului original) sunt mapate pe patru puncte țintă care formează un trapez. Rezultatul — efectul unei imagini înclinate în spațiu.

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

Întrebări frecvente

Cu ce se deosebește Matrix de Camera în Android?

Matrix lucrează cu transformări bidimensionale afine și prospective printr-o singură matrice 3×3. Camera (android.graphics.Camera) — este o clasă de nivel superior care simulează o cameră tridimensională: creează rotație 3D și apoi proiectează rezultatul în Matrix 2D. Camera utilizează Matrix intern.

Cum să rotim Bitmap cu 90 de grade?

Creați o Matrix cu postRotate(90f) și transmiteți-o în Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Rețineți că la rotirea de 90 de grade, lățimea și înălțimea rezultatului se inversează. Pentru rotirea la un unghi arbitrar poate fi necesară tăierea pentru a evita zonele goale.

Cum să obținem transformarea inversă a Matrix?

Utilizați matrix.invert(resultMatrix). Metoda returnează true dacă inversarea este reușită și scrie matricea inversă în resultMatrix. Inversarea poate fi imposibilă dacă matricea este degenerată (de exemplu, la scalare zero). Verificați întotdeauna valoarea returnată.

Care este diferența dintre operațiile pre și post?

pre înmulțește noua transformare la stânga: result = operation × current — operația se aplică înaintea celor curente. post înmulțește la dreapta: result = current × operation — operația se aplică după cele curente. Pentru secvența preRotate + postTranslate: mai întâi rotirea, apoi deplasarea.

Se poate utiliza Matrix în Compose?

Da, Matrix este utilizat în Jetpack Compose prin clasa android.graphics.Matrix în interacțiunea cu Canvas Compose. În Compose sunt disponibile graphicsLayer pentru transformare (scale, rotationX, translationX și altele), dar pentru transformări complexe ale Bitmap, Matrix se aplică în codul drawWithContent sau drawBehind.

Concluzii

  • Matrix — clasă Android pentru transformări afine și prospective cu matrice 3×3
  • Patru tipuri de bază: translate (deplasare), scale (scalare), rotate (rotire), skew (înclinare)
  • Operațiile pre/post controlează ordinea aplicării: pre — înaintea transformărilor curente, post — după transformările curente
  • setPolyToPoly — funcție unică pentru calcularea transformării prospective pentru 4 perechi de puncte
  • Matrix se aplică la Canvas prin concat, la Bitmap prin createBitmap cu Matrix, la puncte prin mapPoints
  • invert calculează transformarea inversă, returnând false pentru matrice degenerate
  • isAffine și isIdentity ajută la clasificarea stării matricei pentru optimizare

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și