Matrix in Android: cos’è, tipi di matrici e lavoro con le trasformazioni

Autore: IT Sectr Pubblicato: 2026-07-22 Tempo di lettura: 9 min

Matrix — una classe dell’SDK Android (android.graphics.Matrix) che rappresenta una trasformazione affine attraverso una matrice 3×3. Viene utilizzata per trasformare oggetti grafici — spostamento, ridimensionamento, rotazione e inclinazione. Secondo la Documentazione per Sviluppatori Android (2026), Matrix è lo strumento principale per lavorare con le trasformazioni in Canvas, Bitmap e Drawable, fornendo un controllo preciso delle coordinate nel disegno personalizzato.

Punti Chiave

  • Matrix — classe Android per trasformazioni affini e prospettiche con una matrice 3×3
  • Operazioni affini: translate (spostare), scale (ridimensionare), rotate (ruotare) e skew (inclinare)
  • Matrix supporta trasformazioni proiettive tramite setPolyToPoly
  • L’ordine delle operazioni è importante — Matrix.concat esegue una moltiplicazione sequenziale
  • Matrix viene applicata a Canvas, Bitmap, RectF, PointF e Path nella grafica Android

Cos’è Matrix in Android?

Matrix (android.graphics.Matrix) — una classe dell’SDK Android che rappresenta una matrice matematica 3×3 utilizzata per trasformare coordinate bidimensionali. Matrix è il blocco fondamentale per tutte le trasformazioni grafiche in Android — dal movimento e ridimensionamento di Canvas alle complesse distorsioni prospettiche di Bitmap.

A differenza di iOS, che utilizza strutture separate CGAffineTransform (affine) e CATransform3D (3D), Android combina trasformazioni affini e prospettiche in un’unica classe Matrix. La matrice 3×3 permette di rappresentare sia le operazioni affini standard (ultima riga [0, 0, 1]) sia le distorsioni prospettiche in cui l’ultima riga contiene valori arbitrari. Ciò offre maggiore flessibilità, ma richiede la comprensione della matematica delle matrici.

Matrix è strettamente integrata con l’API Canvas. Quando uno sviluppatore chiama canvas.translate(), canvas.scale() o canvas.rotate(), questi metodi modificano internamente la matrice del contesto grafico. È possibile ottenere la matrice corrente di Canvas tramite canvas.getMatrix() e applicare manualmente una matrice personalizzata con canvas.setMatrix() o canvas.concat().

Tipi di trasformazioni Matrix

Matrix supporta quattro tipi base di trasformazioni affini: translate, scale, rotate, skew (inclinare). Ogni tipo ha metodi per pre-moltiplicazione (pre), post-moltiplicazione (post) e impostazione (set). La differenza tra preTranslate e postTranslate risiede nell’ordine di moltiplicazione delle matrici, che influisce sulla trasformazione finale quando si combinano le operazioni.

OperazioneMetodoParametriDescrizione
SpostaresetTranslate / preTranslate / postTranslatedx, dySpostamento lungo gli assi X e Y
RidimensionaresetScale / preScale / postScalesx, sy, px, pyRidimensionamento con punto pivot
RuotaresetRotate / preRotate / postRotatedegrees, px, pyRotazione intorno al punto pivot
InclinaresetSkew / preSkew / postSkewkx, kyInclinazione (taglio) lungo gli assi

Spostare — traslazione

Translate modifica la posizione di tutti i punti di un dato spostamento dx, dy. Dx positivo sposta a destra, dy — in basso (nel sistema di coordinate dello schermo Android l’asse Y punta verso il basso). Translate non modifica la forma dell’oggetto — solo la sua posizione. È l’operazione più semplice e più utilizzata per posizionare elementi.

Ridimensionare — scalatura

Scale modifica la dimensione di un oggetto con i fattori sx (lungo X) e sy (lungo Y). I parametri px, py specificano il punto pivot per il ridimensionamento. Se px, py non sono specificati, il ridimensionamento viene eseguito rispetto all’origine (0, 0). Quando sx = sy, l’oggetto si ridimensiona uniformemente. I valori negativi creano un riflesso.

Ruotare — rotazione

Rotate ruota un oggetto di un dato angolo (in gradi) attorno a un punto pivot (px, py). I gradi positivi corrispondono alla rotazione in senso orario (a differenza di iOS/macOS, dove un angolo positivo è antiorario). Se px, py non sono impostati, la rotazione viene eseguita attorno all’origine.

Inclinare — taglio

Skew (taglio) deforma un oggetto inclinandolo lungo l’asse X (kx) o l’asse Y (ky). Un valore di 1.0 inclina di 45 gradi. Skew viene utilizzato per creare effetti di inclinazione, aspetti pseudo-3D e distorsione prospettica.

Struttura di una matrice 3×3

Matrix memorizza i suoi elementi 3×3 in un array interno di 9 valori a virgola mobile (float[9]). L’ordine di memorizzazione è column-major (per colonne), coerente con la rappresentazione matematica standard. L’accesso ai singoli elementi avviene tramite costanti: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X e così via.

Elementi della matrice

La matrice è organizzata come segue: le prime due colonne (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) gestiscono ridimensionamento, rotazione e inclinazione. La terza colonna (MTRANS_X, MTRANS_Y, MPERSP_2) gestisce traslazione e prospettiva. Per le trasformazioni affini, MPERSP_0 e MPERSP_1 sono 0, e MPERSP_2 è 1.

Per ottenere i valori della matrice, utilizzare getValues(float[] values), che riempie un array di 9 elementi. Per impostarli, utilizzare setValues(float[] values). Ciò consente la manipolazione diretta della matrice per trasformazioni personalizzate complesse oltre i metodi standard translate, scale, rotate e skew.

Verifica del tipo di matrice

Matrix fornisce diversi metodi per classificare lo stato corrente. isIdentity() verifica se la matrice è identità. isAffine() verifica se contiene solo trasformazioni affini (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Questi controlli sono utili per l’ottimizzazione: se la matrice è identità, la trasformazione può essere saltata.

Operazioni di base con Matrix

Matrix supporta diverse categorie di operazioni: impostazione (set), pre-moltiplicazione (pre), post-moltiplicazione (post), concatenazione (concat), inversione (invert) e mappatura (map). Ogni categoria ha il suo scopo nella costruzione di trasformazioni complesse.

Operazioni Pre e Post

preTranslate moltiplica la matrice corrente a sinistra per la matrice di traslazione: result = translate × current. postTranslate moltiplica a destra: result = current × translate. La differenza sta nell’ordine di applicazione: le operazioni pre vengono applicate prima delle trasformazioni correnti, le operazioni post dopo. Lo stesso vale per preScale, postScale, preRotate, postRotate e preSkew, postSkew.

Inversione e concatenazione

invert(Matrix inverse) calcola la matrice inversa. Se la matrice originale è singolare (determinante zero), restituisce false. concat(Matrix other) moltiplica la matrice corrente per quella fornita: set = set × other. Per l’ordine inverso, utilizzare setConcat(other, this).

Map — applicazione a punti e rettangoli

mapRect(RectF rect) trasforma un rettangolo e restituisce il risultato in un nuovo RectF. mapPoints(float[] dst, float[] src) trasforma un array di punti. mapVectors(float[] dst, float[] src) trasforma vettori — senza considerare la traslazione. mapRect è utile per calcolare i bounding box dopo la trasformazione.

Applicazione in Canvas e Bitmap

Matrix viene utilizzata attivamente in due scenari chiave della grafica Android: trasformazione di Canvas e trasformazione di Bitmap. In entrambi i casi, Matrix determina come verrà modificata l’uscita grafica.

Trasformazione di Canvas tramite Matrix

Canvas fornisce canvas.setMatrix(matrix) per la sostituzione completa della matrice corrente e canvas.concat(matrix) per moltiplicare la trasformazione corrente per quella fornita. Dopo aver applicato Matrix, tutto il disegno successivo — chiamate drawBitmap, drawRect, drawPath — viene eseguito nel sistema di coordinate trasformato. Canvas mantiene anche il proprio stack di stati salvati tramite save() e restore().

Trasformazione di Bitmap tramite Matrix

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) crea un nuovo Bitmap con la trasformazione fornita applicata. Questo è un potente strumento per creare copie ridimensionate, ruotate o distorte di immagini senza perdere il Bitmap originale. Il parametro filter controlla l’anti-aliasing durante l’interpolazione dei pixel.

setPolyToPoly — trasformazioni prospettiche

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — una capacità unica di Matrix senza equivalente diretto in CGAffineTransform. Calcola una matrice che trasforma punti dati da un poligono a un altro. Con pointCount = 4, viene creata una trasformazione prospettica (proiettiva) completa, consentendo la sovrapposizione di Bitmap con distorsione prospettica.

Esempi di codice Kotlin

Vediamo esempi pratici di utilizzo di Matrix per la trasformazione grafica in un’applicazione Android con Kotlin.

Trasformazioni affini di base

L’esempio crea un Matrix per una trasformazione combinata: traslazione di (100, 50), ridimensionamento di 1.5x e rotazione di 45 gradi. L’uso di postTranslate dopo preRotate e preScale modifica l’ordine di applicazione delle operazioni.

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

// Applicazione ai punti
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// Applicazione al rettangolo
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

Trasformazione di Canvas con save e restore

L’esempio dimostra l’applicazione di Matrix a Canvas in onDraw per ruotare e ridimensionare un cerchio attorno al suo centro. Salvare e ripristinare lo stato di Canvas garantisce che la trasformazione non influisca sugli elementi di disegno successivi.

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

Distorsione prospettica tramite setPolyToPoly

L’esempio utilizza setPolyToPoly per creare una distorsione prospettica di un Bitmap. Quattro punti sorgente (angoli del rettangolo originale) vengono mappati a quattro punti destinazione che formano un trapezio. Il risultato è un effetto di immagine inclinata nello spazio.

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

Domande Frequenti

Qual è la differenza tra Matrix e Camera in Android?

Matrix lavora con trasformazioni affini e prospettiche bidimensionali attraverso un’unica matrice 3×3. Camera (android.graphics.Camera) è una classe di livello superiore che simula una fotocamera tridimensionale: crea una rotazione 3D e poi proietta il risultato in una Matrix 2D. Camera utilizza Matrix internamente.

Come ruotare un Bitmap di 90 gradi?

Creare un Matrix con postRotate(90f) e passarlo a Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Notare che ruotando di 90 gradi, larghezza e altezza del risultato si scambiano. Per rotazioni ad angolo arbitrario, potrebbe essere necessario ritagliare per evitare aree vuote.

Come ottenere la trasformazione inversa di Matrix?

Utilizzare matrix.invert(resultMatrix). Il metodo restituisce true se l’inversione ha successo e scrive la matrice inversa in resultMatrix. L’inversione può essere impossibile se la matrice è singolare (ad esempio, con scala zero). Controllare sempre il valore restituito.

Qual è la differenza tra operazioni pre e post?

pre moltiplica la nuova trasformazione a sinistra: result = operation × current — l’operazione viene applicata prima di quelle correnti. post moltiplica a destra: result = current × operation — l’operazione viene applicata dopo. Per una sequenza preRotate + postTranslate: prima rotazione, poi traslazione.

Si può usare Matrix in Compose?

, Matrix viene utilizzata in Jetpack Compose attraverso la classe android.graphics.Matrix in interazione con Canvas Compose. In Compose, graphicsLayer è disponibile per le trasformazioni (scale, rotationX, translationX e altre), ma per trasformazioni complesse di Bitmap, Matrix viene utilizzata nel codice drawWithContent o drawBehind.

Riepilogo

  • Matrix — classe Android per trasformazioni affini e prospettiche con una matrice 3×3
  • Quattro tipi base: translate, scale, rotate, skew
  • Operazioni pre/post controllano l’ordine di applicazione: pre — prima delle correnti, post — dopo le trasformazioni correnti
  • setPolyToPoly — funzione unica per calcolare la trasformazione prospettica da 4 coppie di punti
  • Matrix viene applicata a Canvas tramite concat, a Bitmap tramite createBitmap con Matrix, ai punti tramite mapPoints
  • invert calcola la trasformazione inversa, restituendo false per matrici singolari
  • isAffine e isIdentity aiutano a classificare lo stato della matrice per l’ottimizzazione

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche