Matrix у Android-у: шта је то, врсте матрица и рад са трансформацијама

Аутор: IT Sectr Објављено: 2026-07-22 Време читања: 9 мин

Matrix — је класа из Android SDK (android.graphics.Matrix) која представља афину трансформацију кроз матрицу 3×3. Користи се за трансформацију графичких објеката — померање, скалирање, ротацију и нагињање. Према Android Developers Documentation (2026), Matrix је основни алат за рад са трансформацијама у Canvas, Bitmap и Drawable, обезбеђујући прецизну контролу координата при прилагођеном цртању.

Главно

  • Matrix — Android класа за афине и перспективне трансформације са матрицом 3×3
  • Афине операције: translate (померај), scale (размера), rotate (ротација) и skew (нагиб)
  • Matrix подржава перспективне (projective) трансформације кроз setPolyToPoly
  • Редослед примене операција је важан — Matrix.concat изводи секвенцијално множење
  • Matrix се примењује на Canvas, Bitmap, RectF, PointF и Path у Android графици

Шта је Matrix у Android-у?

Matrix (android.graphics.Matrix) — је класа Android SDK која представља математичку матрицу 3×3, која се користи за трансформацију дводимензионалних координата. Matrix је основни градивни блок за све графичке трансформације у Android-у — од померања и скалирања Canvas-а до сложених перспективних изобличења Bitmap-а.

За разлику од iOS-а, где се користе засебне структуре CGAffineTransform (афине) и CATransform3D (3D), Android обједињује афине и перспективне трансформације у једној класи Matrix. Матрица 3×3 омогућава представљање како стандардних афиних операција (последњи ред [0, 0, 1]), тако и перспективних изобличења када последњи ред садржи произвољне вредности. Ово даје више флексибилности, али захтева разумевање математике матрица.

Matrix је тесно интегрисан са Canvas API. Када програмер позове canvas.translate(), canvas.scale() или canvas.rotate(), ове методе интерно модификују матрицу графичког контекста. Тренутна матрица Canvas-а може се добити кроз canvas.getMatrix(), а ручно применити прилагођена — кроз canvas.setMatrix() или canvas.concat().

Врсте трансформација Matrix

Matrix подржава четири основна типа афиних трансформација: translate, scale, rotate, skew (нагиб). Сваки тип има методе за пре-множење (pre), пост-множење (post) и постављање (set). Разлика између preTranslate и postTranslate је у редоследу множења матрица, што утиче на коначну трансформацију при комбиновању.

ОперацијаМетодаПараметриОпис
TranslatesetTranslate / preTranslate / postTranslatedx, dyПомерај дуж X и Y оса
ScalesetScale / preScale / postScalesx, sy, px, pyСкалирање са референтном тачком
RotatesetRotate / preRotate / postRotatedegrees, px, pyРотација око референтне тачке
SkewsetSkew / preSkew / postSkewkx, kyНагиб (клизање) дуж оса

Translate — померај

Translate мења положај свих тачака за дати померај dx, dy. Позитиван dx помера удесно, dy — надоле (у координатном систему екрана Android-а Y оса је усмерена надоле). Translate не мења облик објекта — само његову позицију. Ово је најједноставнија и најчешће коришћена операција за позиционирање елемената.

Scale — размера

Scale мења величину објекта са коефицијентима sx (дуж X) и sy (дуж Y). Параметри px, py задају референтну тачку скалирања (pivot point). Ако px, py нису наведени, скалирање се врши у односу на почетак координата (0, 0). При sx = sy објекат се равномерно скалира. Негативне вредности стварају рефлексију.

Rotate — ротација

Rotate ротира објекат за дати угао (у степенима) око референтне тачке (px, py). Позитивна вредност степени одговара ротацији у смеру казаљке на сату (за разлику од iOS/macOS, где је позитиван угао супротно од смера казаљке на сату). Ако px, py нису наведени, ротација се врши око почетка координата.

Skew — нагиб

Skew (клизање) деформише објекат нагињући га дуж X осе (kx) или Y осе (ky). Вредност 1.0 нагиње за 45 степени. Skew се користи за стварање ефеката нагиба, имитацију тродимензионалног приказа (псеудо-3D) и изобличење перспективе.

Структура матрице 3×3

Matrix чува елементе матрице 3×3 у интерном низу од 9 вредности са покретним зарезом (float[9]). Редослед чувања — column-major (по колонама), што одговара стандардном математичком приказу. Приступ појединачним елементима се врши преко константи: Matrix.MSCALE_X, Matrix.MSKEW_Y, Matrix.MTRANS_X и тако даље.

Елементи матрице

Матрица је организована на следећи начин: прве две колоне (MSCALE_X, MSKEW_X, MSKEW_Y, MSCALE_Y) одговарају за скалирање, ротацију и нагиб. Трећа колона (MTRANS_X, MTRANS_Y, MPERSP_2) — за померај и перспективу. За афину трансформацију MPERSP_0 и MPERSP_1 су једнаки 0, а MPERSP_2 је једнак 1.

За добијање вредности матрице користи се getValues(float[] values), који попуњава низ од 9 елемената. За постављање — setValues(float[] values). Ово омогућава директно манипулисање матрицом за сложене прилагођене трансформације које превазилазе стандардне методе translate, scale, rotate и skew.

Провера типа матрице

Matrix пружа неколико метода за класификацију тренутног стања. isIdentity() проверава да ли је матрица јединична. isAffine() — да ли садржи само афине трансформације (MPERSP_0 = 0, MPERSP_1 = 0, MPERSP_2 = 1). Ове провере су корисне за оптимизацију: ако је матрица јединична, трансформација се може прескочити.

Основне операције са Matrix

Matrix подржава неколико категорија операција: постављање (set), пре-множење (pre), пост-множење (post), конкатенација (concat), инверзија (invert) и мапирање (map). Свака категорија решава свој задатак при изградњи сложених трансформација.

Pre и Post операције

preTranslate множи тренутну матрицу са леве стране матрицом помераја: result = translate × current. postTranslate множи са десне стране: result = current × translate. Разлика је у редоследу примене: pre-операције се примењују пре текућих трансформација, post-операције — после. Аналогно раде preScale, postScale, preRotate, postRotate и preSkew, postSkew.

Инверзија и конкатенација

invert(Matrix inverse) израчунава инверзну матрицу. Ако је изворна матрица дегенерисана (детерминанта је нула), враћа се false. concat(Matrix other) множи тренутну матрицу са прослеђеном: set = set × other. За обрнути редослед користите setConcat(other, this).

Map — примена на тачке и правоугаонике

mapRect(RectF rect) трансформише правоугаоник и враћа резултат у нови RectF. mapPoints(float[] dst, float[] src) трансформише низ тачака. mapVectors(float[] dst, float[] src) трансформише векторе — без узимања у обзир помераја (translate). mapRect је користан за израчунавање bounding box-а након трансформације.

Примена у Canvas и Bitmap

Matrix се активно користи у два кључна сценарија Android графике: трансформација Canvas-а и трансформација Bitmap-а. У оба случаја Matrix одређује како ће графички излаз бити измењен.

Canvas трансформација кроз Matrix

Canvas пружа методе canvas.setMatrix(matrix) за потпуну замену тренутне матрице и canvas.concat(matrix) за множење тренутне трансформације са прослеђеном. Након примене Matrix, сав накнадни цртеж — позиви drawBitmap, drawRect, drawPath — извршава се у трансформисаном координатном систему. Canvas такође чува свој стек сачуваних стања кроз save() и restore().

Bitmap трансформација кроз Matrix

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix matrix, boolean filter) креира нови Bitmap са применом дате трансформације. Ово је моћан алат за креирање скалираних, ротираних или деформисаних копија слика без губитка оригиналног Bitmap-а. Параметар filter контролише изглађивање при интерполацији пиксела.

setPolyToPoly — перспективне трансформације

setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) — јединствена могућност Matrix-а, без директног аналога у CGAffineTransform. Она израчунава матрицу која трансформише дате тачке из једног полигона у други. При pointCount = 4 ствара се потпуна перспективна (projective) трансформација, омогућавајући наношење Bitmap-а са изобличењем перспективе.

Примери кода у Kotlin

Размотримо практичне примере коришћења Matrix за трансформацију графике у Android апликацији на Kotlin-у.

Основне афине трансформације

Пример креира Matrix за комбиновану трансформацију: померај за (100, 50), скалирање 1.5 пута и ротацију за 45 степени. Коришћење postTranslate након preRotate и preScale мења редослед примене операција.

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

// Примена на тачке
val pts = floatArrayOf(0f, 0f, 100f, 100f)
matrix.mapPoints(pts)

// Примена на правоугаоник
val rect = RectF(0f, 0f, 200f, 100f)
matrix.mapRect(rect)

Canvas трансформација са save и restore

Пример демонстрира примену Matrix на Canvas у onDraw за ротацију и скалирање круга око његовог центра. Чување и враћање стања Canvas-а гарантује да трансформација неће утицати на накнадне елементе цртања.

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

Перспективно изобличење кроз setPolyToPoly

Пример користи setPolyToPoly за стварање перспективног изобличења Bitmap-а. Четири изворне тачке (углови оригиналног правоугаоника) мапирају се на четири циљне тачке које формирају трапез. Резултат — ефекат слике нагнуте у простору.

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

Често постављана питања

По чему се Matrix разликује од Camera у Android-у?

Matrix ради са дводимензионалним афиним и перспективним трансформацијама кроз једну матрицу 3×3. Camera (android.graphics.Camera) — је класа вишег нивоа која имитира тродимензионалну камеру: ствара 3D ротацију и затим пројектује резултат у 2D Matrix. Camera интерно користи Matrix.

Како ротирати Bitmap за 90 степени?

Направите Matrix са postRotate(90f) и проследите у Bitmap.createBitmap(original, 0, 0, w, h, matrix, true). Имајте у виду да при ротацији за 90 степени ширина и висина резултата замењују места. За ротацију за произвољан угао може бити потребно обрезивање да би се избегле празне области.

Како добити инверзну трансформацију Matrix?

Користите matrix.invert(resultMatrix). Метода враћа true ако је инверзија успешна и уписује инверзну матрицу у resultMatrix. Инверзија може бити немогућа ако је матрица дегенерисана (нпр. при нултом скалирању). Увек проверавајте повратну вредност.

Која је разлика између pre и post операција?

pre множи нову трансформацију са леве стране: result = operation × current — операција се примењује пре текућих. post множи са десне стране: result = current × operation — операција се примењује после. За секвенцу preRotate + postTranslate: прво ротација, затим померај.

Може ли се Matrix користити у Compose-у?

Да, Matrix се користи у Jetpack Compose кроз класу android.graphics.Matrix у интеракцији са Canvas Compose. У Compose-у су доступни graphicsLayer за трансформацију (scale, rotationX, translationX и други), али за сложене трансформације Bitmap-а Matrix се примењује у коду drawWithContent или drawBehind.

Закључак

  • Matrix — Android класа за афине и перспективне трансформације са матрицом 3×3
  • Четири основна типа: translate (померај), scale (размера), rotate (ротација), skew (нагиб)
  • pre/post операције управљају редоследом примене: pre — пре текућих, post — после текућих трансформација
  • setPolyToPoly — јединствена функција за израчунавање перспективне трансформације за 4 пара тачака
  • Matrix се примењује на Canvas кроз concat, на Bitmap кроз createBitmap са Matrix, на тачке кроз mapPoints
  • invert израчунава инверзну трансформацију, враћајући false за дегенерисане матрице
  • isAffine и isIdentity помажу у класификацији стања матрице за оптимизацију

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође