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.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().
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í.
| Operace | Metoda | Parametry | Popis |
|---|---|---|---|
| Translate | setTranslate / preTranslate / postTranslate | dx, dy | Posun podél os X a Y |
| Scale | setScale / preScale / postScale | sx, sy, px, py | Škálování s referenčním bodem |
| Rotate | setRotate / preRotate / postRotate | degrees, px, py | Otáčení kolem referenčního bodu |
| Skew | setSkew / preSkew / postSkew | kx, ky | Zkosení (posun) podél os |
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ě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áčí 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 (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.
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.
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.
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.
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í.
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.
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).
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.
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.
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().
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(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.
Podívejme se na praktické příklady použití Matrix pro transformaci grafiky v Android aplikaci v Kotlin.
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í.
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)
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í.
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()
}
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.
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
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.
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.
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.
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.
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í
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í.
Přečtěte si také