二维图形变换的矩阵如下:
|ScaleX SkewX TransX|
|SkewY ScaleY TransY|
|Persp0 Persp1 Persp2|
ScaleX:x方向缩放倍率
ScaleY:y方向缩放倍率
TransX:x方向平移值
TransY:y方向平移值
SkewX:x方向错切值
SkewY:y方向错切值
Persp:齐次坐标的值,一般取值0或1。
graphics包中的Matrix类的方法调用native计算,jni调用了skia库中SkMatrix.cpp文件下的函数计算,各个函数实际上都是在对二维变换矩阵进行赋值:
void SkMatrix::setScale(SkScalar sx, SkScalar sy) { if (1 == sx && 1 == sy) { this->reset(); } else { fMat[kMScaleX] = sx; fMat[kMScaleY] = sy; fMat[kMPersp2] = 1; fMat[kMTransX] = fMat[kMTransY] = fMat[kMSkewX] = fMat[kMSkewY] = fMat[kMPersp0] = fMat[kMPersp1] = 0; this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); } }
这是以原点为中心进行缩放的矩阵赋值。
void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { if (1 == sx && 1 == sy) { this->reset(); } else { fMat[kMScaleX] = sx; fMat[kMScaleY] = sy; fMat[kMTransX] = px - sx * px; fMat[kMTransY] = py - sy * py; fMat[kMPersp2] = 1; fMat[kMSkewX] = fMat[kMSkewY] = fMat[kMPersp0] = fMat[kMPersp1] = 0; this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); } }
这是以指定坐标(px, py)为中心点进行缩放的矩阵赋值。与上一个函数对比可以发现,不仅进行了缩放还进行了平移,所以才可以表现为在指定点处缩放。
void SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { if (!dx && !dy) { return; } if (this->hasPerspective()) { SkMatrix m; m.setTranslate(dx, dy); this->preConcat(m); } else { fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); } } void SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { if (!dx && !dy) { return; } if (this->hasPerspective()) { SkMatrix m; m.setTranslate(dx, dy); this->postConcat(m); } else { fMat[kMTransX] += dx; fMat[kMTransY] += dy; this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); } } static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d) { return a * b + c * d; }
上面的这三个函数说明了pre和post的区别,假如有如下操作:
(1)
Matrix.scale(0.5, 0.5);
Matrix.preTranslate(100, 100);
(2)
Matrix.scale(0.5, 0.5);
Matrix.postTranslate(100, 100);
第一段代码会平移(100*0.5, 100*0.5),第二段代码会平移(100, 100),post不受之前的矩阵变换的影响。
其它函数的pre和post的意思都是如此。
另外:
scale缩放取值为-1时可以得到镜像矩阵
protected static Matrix getHorizontalMatrix(float width) { Matrix flipHorizontalMatrix = new Matrix(); flipHorizontalMatrix.setScale(-1, 1); flipHorizontalMatrix.postTranslate(width, 0); return flipHorizontalMatrix; }
上面的矩阵表示对原图进行水平镜像变换。
时间: 2024-10-07 19:04:25