Matrix v Androidu: co to je, typy matic a práce s transformacemi

Autor: IT Sectr Publikováno: 2026-07-22 Doba čtení: 9 min

Matrix — je třída z Android SDK (android.graphics.Matrix), která představuje afinní transformaci pomocí matice 3×3. Používá se pro transformaci grafických objektů — posouvání, škálování, otáčení a zkosení. Podle Android Developers Documentation (2026) je Matrix hlavním nástrojem pro práci s transformacemi v Canvas, Bitmap a Drawable, poskytující přesnou kontrolu souřadnic při vlastním kreslení.

Hlavní body

  • Matrix — Android třída pro afinní a perspektivní transformace s maticí 3×3
  • Afinní operace: translate (posun), scale (měřítko), rotate (otáčení) a skew (zkosení)
  • Matrix podporuje perspektivní (projektivní) transformace pomocí setPolyToPoly
  • Pořadí aplikace operací je důležité — Matrix.concat provádí sekvenční násobení
  • Matrix se aplikuje na Canvas, Bitmap, RectF, PointF a Path v Android grafice

Co je Matrix v Androidu?

Matrix (android.graphics.Matrix) — je třída Android SDK, která představuje matematickou matici 3×3 používanou pro transformaci dvourozměrných souřadnic. Matrix je základním stavebním blokem pro všechny grafické transformace v Androidu — od posouvání a škálování Canvasu až po složité perspektivní deformace Bitmap.

Na rozdíl od iOS, kde se používají samostatné struktury CGAffineTransform (afinní) a CATransform3D (3D), Android spojuje afinní a perspektivní transformace do jedné třídy Matrix. Matice 3×3 umožňuje reprezentovat jak standardní afinní operace (poslední řádek [0, 0, 1]), tak perspektivní deformace, když poslední řádek obsahuje libovolné hodnoty. To poskytuje větší flexibilitu, ale vyžaduje porozumění matematice matic.

Matrix je úzce integrován s Canvas API. Když vývojář zavolá canvas.translate(), canvas.scale() nebo canvas.rotate(), tyto metody interně modifikují matici grafického kontextu. Aktuální matici Canvasu lze získat pomocí canvas.getMatrix() a vlastní matici lze ručně aplikovat pomocí canvas.setMatrix() nebo canvas.concat().

Typy transformací Matrix

Matrix podporuje čtyři základní typy afinních transformací: translate, scale, rotate, skew (zkosení). Každý typ má metody pro před-násobení (pre), po-násobení (post) a nastavení (set). Rozdíl mezi preTranslate a postTranslate spočívá v pořadí násobení matic, což ovlivňuje konečnou transformaci při kombinování.

OperaceMetodaParametryPopis
TranslatesetTranslate / preTranslate / postTranslatedx, dyPosun podél os X a Y
ScalesetScale / preScale / postScalesx, sy, px, pyŠkálování s referenčním bodem
RotatesetRotate / preRotate / postRotatedegrees, px, pyOtáčení kolem referenčního bodu
SkewsetSkew / preSkew / postSkewkx, kyZkosení (posun) podél os

Translate — posun

Translate mění polohu všech bodů o daný posun dx, dy. Kladné dx posouvá doprava, dy — dolů (v souřadnicovém systému obrazovky Androidu je osa Y orientována dolů). Translate nemění tvar objektu — pouze jeho pozici. To je nejjednodušší a nejčastěji používaná operace pro pozicování prvků.

Scale — měřítko

Scale mění velikost objektu s koeficienty sx (podél X) a sy (podél Y). Parametry px, py určují referenční bod škálování (pivot point). Pokud px, py nejsou zadány, škálování se provádí vzhledem k počátku souřadnic (0, 0). Při sx = sy se objekt škáluje rovnoměrně. Záporné hodnoty vytvářejí odraz.

Rotate — otáčení

Rotate otáčí objekt o daný úhel (ve stupních) kolem referenčního bodu (px, py). Kladná hodnota stupňů odpovídá otáčení ve směru hodinových ručiček (na rozdíl od iOS/macOS, kde kladný úhel je proti směru hodinových ručiček). Pokud px, py nejsou zadány, otáčení se provádí kolem počátku souřadnic.

Skew — zkosení

Skew (posun) deformuje objekt zkosením podél osy X (kx) nebo osy Y (ky). Hodnota 1.0 zkosí o 45 stupňů. Skew se používá pro vytváření efektů zkosení, simulaci trojrozměrného pohledu (pseudo-3D) a deformaci perspektivy.

Struktura matice 3×3

Matrix ukládá prvky matice 3×3 do interního pole 9 hodnot s plovoucí čárkou (float[9]). Pořadí ukládání je column-major (po sloupcích), což odpovídá standardní matematické reprezentaci. Přístup k jednotlivým prvkům se provádí pomocí konstant: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X a tak dále.

Prvky matice

Matice je organizována následovně: první dva sloupce (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) odpovídají za škálování, otáčení a zkosení. Třetí sloupec (MTRANS_X, MTRANS_Y, MPERSP_2) — za posun a perspektivu. Pro afinní transformaci jsou MPERSP_0 a MPERSP_1 rovny 0 a MPERSP_2 je roven 1.

Pro získání hodnot matice se používá getValues(float[] values), který naplní pole 9 prvků. Pro nastavení — setValues(float[] values). To umožňuje přímou manipulaci s maticí pro složité vlastní transformace přesahující standardní metody translate, scale, rotate a skew.

Kontrola typu matice

Matrix poskytuje několik metod pro klasifikaci aktuálního stavu. isIdentity() kontroluje, zda je matice jednotková. isAffine() — zda obsahuje pouze afinní transformace (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Tyto kontroly jsou užitečné pro optimalizaci: pokud je matice jednotková, transformaci lze přeskočit.

Základní operace s Matrix

Matrix podporuje několik kategorií operací: nastavení (set), před-násobení (pre), po-násobení (post), konkatenace (concat), inverze (invert) a mapování (map). Každá kategorie řeší svůj úkol při vytváření složitých transformací.

Pre a Post operace

preTranslate násobí aktuální matici zleva maticí posunu: result = translate × current. postTranslate násobí zprava: result = current × translate. Rozdíl je v pořadí aplikace: pre-operace se aplikují před aktuálními transformacemi, post-operace — po. Analogicky fungují preScale, postScale, preRotate, postRotate a preSkew, postSkew.

Inverze a konkatenace

invert(Matrix inverse) vypočítá inverzní matici. Pokud je zdrojová matice degenerovaná (determinant je nula), vrací se false. concat(Matrix other) násobí aktuální matici předanou maticí: set = set × other. Pro opačné pořadí použijte setConcat(other, this).

Map — aplikace na body a obdélníky

mapRect(RectF rect) transformuje obdélník a vrací výsledek do nového RectF. mapPoints(float[] dst, float[] src) transformuje pole bodů. mapVectors(float[] dst, float[] src) transformuje vektory — bez uvažování posunu (translate). mapRect je užitečný pro výpočet bounding box po transformaci.

Použití v Canvas a Bitmap

Matrix se aktivně používá ve dvou klíčových scénářích Android grafiky: transformace Canvasu a transformace Bitmap. V obou případech Matrix určuje, jak bude grafický výstup změněn.

Transformace Canvasu pomocí Matrix

Canvas poskytuje metody canvas.setMatrix(matrix) pro úplné nahrazení aktuální matice a canvas.concat(matrix) pro násobení aktuální transformace předanou. Po aplikaci Matrix se veškeré následné kreslení — volání drawBitmap, drawRect, drawPath — provádí v transformovaném souřadnicovém systému. Canvas také udržuje vlastní zásobník uložených stavů pomocí save() a restore().

Transformace Bitmap pomocí Matrix

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) vytváří novou Bitmap s aplikací dané transformace. To je mocný nástroj pro vytváření škálovaných, otočených nebo deformovaných kopií obrázků bez ztráty původní Bitmap. Parametr filter řídí vyhlazování při interpolaci pixelů.

setPolyToPoly — perspektivní transformace

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — jedinečná schopnost Matrix, bez přímé analogie v CGAffineTransform. Vypočítá matici, která transformuje dané body z jednoho polygonu do druhého. Při pointCount = 4 se vytváří plná perspektivní (projektivní) transformace, umožňující aplikovat Bitmap s deformací perspektivy.

Příklady kódu v Kotlin

Podívejme se na praktické příklady použití Matrix pro transformaci grafiky v Android aplikaci v Kotlin.

Základní afinní transformace

Příklad vytváří Matrix pro kombinovanou transformaci: posun o (100, 50), 1.5 násobné škálování a otočení o 45 stupňů. Použití postTranslate po preRotate a preScale mění pořadí aplikace operací.

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

// Aplikace na body
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// Aplikace na obdélník
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

Transformace Canvasu s save a restore

Příklad demonstruje aplikaci Matrix na Canvas v onDraw pro otáčení a škálování kruhu kolem jeho středu. Uložení a obnovení stavu Canvasu zaručuje, že transformace neovlivní následující prvky kreslení.

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

Perspektivní deformace pomocí setPolyToPoly

Příklad používá setPolyToPoly pro vytvoření perspektivní deformace Bitmap. Čtyři zdrojové body (rohy původního obdélníku) jsou mapovány na čtyři cílové body tvořící lichoběžník. Výsledkem je efekt obrazu nakloněného v prostoru.

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

Často kladené otázky

Čím se liší Matrix od Camera v Androidu?

Matrix pracuje s dvourozměrnými afinními a perspektivními transformacemi pomocí jedné matice 3×3. Camera (android.graphics.Camera) — je třída vyšší úrovně, která simuluje trojrozměrnou kameru: vytváří 3D rotaci a poté promítá výsledek do 2D Matrix. Camera interně používá Matrix.

Jak otočit Bitmap o 90 stupňů?

Vytvořte Matrix s postRotate(90f) a předejte do Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Mějte na paměti, že při otočení o 90 stupňů se šířka a výška výsledku prohodí. Pro otočení o libovolný úhel může být vyžadováno oříznutí, aby se předešlo prázdným oblastem.

Jak získat inverzní transformaci Matrix?

Použijte matrix.invert(resultMatrix). Metoda vrací true, pokud je inverze úspěšná, a zapisuje inverzní matici do resultMatrix. Inverze může být nemožná, pokud je matice degenerovaná (například při nulovém měřítku). Vždy kontrolujte návratovou hodnotu.

Jaký je rozdíl mezi pre a post operacemi?

pre násobí novou transformaci zleva: result = operation × current — operace se aplikuje před aktuálními transformacemi. post násobí zprava: result = current × operation — operace se aplikuje po aktuálních transformacích. Pro sekvenci preRotate + postTranslate: nejprve otočení, poté posun.

Lze použít Matrix v Compose?

Ano, Matrix se používá v Jetpack Compose prostřednictvím třídy android.graphics.Matrix v interakci s Canvas Compose. V Compose je k dispozici graphicsLayer pro transformaci (scale, rotationX, translationX a další), ale pro složité transformace Bitmap se Matrix aplikuje v kódu drawWithContent nebo drawBehind.

Shrnutí

  • Matrix — Android třída pro afinní a perspektivní transformace s maticí 3×3
  • Čtyři základní typy: translate (posun), scale (měřítko), rotate (otáčení), skew (zkosení)
  • Operace pre/post řídí pořadí aplikace: pre — před aktuálními transformacemi, post — po aktuálních transformacích
  • setPolyToPoly — jedinečná funkce pro výpočet perspektivní transformace pro 4 páry bodů
  • Matrix se aplikuje na Canvas pomocí concat, na Bitmap pomocí createBitmap s Matrix, na body pomocí mapPoints
  • invert vypočítá inverzní transformaci a vrací false pro degenerované matice
  • isAffine a isIdentity pomáhají klasifikovat stav matice pro optimalizaci

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také