下面列出了android.graphics.Matrix#MSKEW_Y 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
void seamlesslyRotate(SurfaceControl.Transaction t, int oldRotation, int newRotation) {
final WindowState w = mWin;
// We rotated the screen, but have not received a new buffer with the correct size yet. In
// the mean time, we rotate the buffer we have to the new orientation.
final Matrix transform = mService.mTmpTransform;
transformToRotation(oldRotation, newRotation, w.mFrame.width(), w.mFrame.height(),
transform);
transform.getValues(mService.mTmpFloats);
float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
float nx = mService.mTmpFloats[Matrix.MTRANS_X];
float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
mSurfaceController.setPosition(t, nx, ny, false);
mSurfaceController.setMatrix(t, DsDx * w.mHScale, DtDx * w.mVScale, DtDy
* w.mHScale, DsDy * w.mVScale, false);
}
/**
* android.graphics.Matrixの3x3行列をOpenGLの4x4(列優先)行列に変換する
* (アフィン変換のみ)
* |a11 a12 a13| |0 1 2| |a11 a12 0 a13| |0 4 8 12|
* |a21 a22 a23| |3 4 5| |a21 a22 0 a23| |1 5 9 13|
* |a31 a32 a33| |6 7 8| => | 0 0 1 0| |2 6 10 14|
* |a31 a32 0 a33| |3 7 11 15|
* @param transform
* @param result
* @return
*/
@NonNull
@Size(min=16)
public static float[] toGLMatrix(@NonNull final Matrix transform,
@NonNull @Size(min=16) final float[] result,
@NonNull @Size(min=9) final float[] aMatrix) {
transform.getValues(aMatrix);
result[ 0] = aMatrix[Matrix.MSCALE_X];
result[ 1] = aMatrix[Matrix.MSKEW_Y];
result[ 2] = 0;
result[ 3] = aMatrix[Matrix.MPERSP_0];
result[ 4] = aMatrix[Matrix.MSKEW_X];
result[ 5] = aMatrix[Matrix.MSCALE_Y];
result[ 6] = 0;
result[ 7] = aMatrix[Matrix.MPERSP_1];
result[ 8] = 0;
result[ 9] = 0;
result[10] = 1;
result[11] = 0;
result[12] = aMatrix[Matrix.MTRANS_X];
result[13] = aMatrix[Matrix.MTRANS_Y];
result[14] = 0;
result[15] = aMatrix[Matrix.MPERSP_2];
return result;
}
/**
* OpenGLの4x4(列優先)行列をandroid.graphics.Matrixの3x3行列に変換する
* (アフィン変換のみ)
* @param transform
* @param result
* @param aMatrix
* @return
*/
public static Matrix toAndroidMatrix(
@NonNull @Size(min=16)final float[] transform,
@NonNull final Matrix result,
@NonNull @Size(min=9) final float[] aMatrix) {
aMatrix[Matrix.MSCALE_X] = transform[ 0];
aMatrix[Matrix.MSKEW_Y] = transform[ 1];
aMatrix[Matrix.MPERSP_0] = transform[ 3];
aMatrix[Matrix.MSKEW_X] = transform[ 4];
aMatrix[Matrix.MSCALE_Y] = transform[ 5];
aMatrix[Matrix.MPERSP_1] = transform[ 7];
aMatrix[Matrix.MTRANS_X] = transform[12];
aMatrix[Matrix.MTRANS_Y] = transform[13];
aMatrix[Matrix.MPERSP_2] = transform[15];
result.setValues(aMatrix);
return result;
}
public static float[] LoadGraphicsMatrix(Matrix matrix) {
float m[] = new float[16];
float v[] = new float[9];
matrix.getValues(v);
m[0] = v[Matrix.MSCALE_X]; //m.a;
m[1] = v[Matrix.MSKEW_X]; //m.b;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = v[Matrix.MSKEW_Y]; //m.c;
m[5] = v[Matrix.MSCALE_Y]; //m.d;
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = v[Matrix.MTRANS_X]; //m.tx;
m[13] = v[Matrix.MTRANS_Y]; //m.ty;
m[14] = 0.0f;
m[15] = 1.0f;
return m;
}
private void syncCharts() {
Matrix srcMatrix;
float[] srcVals = new float[9];
Matrix dstMatrix;
float[] dstVals = new float[9];
// get src chart translation matrix:
srcMatrix = srcChart.getViewPortHandler().getMatrixTouch();
srcMatrix.getValues(srcVals);
// apply X axis scaling and position to dst charts:
for (Chart dstChart : dstCharts) {
dstMatrix = dstChart.getViewPortHandler().getMatrixTouch();
dstMatrix.getValues(dstVals);
dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
dstVals[Matrix.MSKEW_X] = srcVals[Matrix.MSKEW_X];
dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
dstVals[Matrix.MSKEW_Y] = srcVals[Matrix.MSKEW_Y];
dstVals[Matrix.MSCALE_Y] = srcVals[Matrix.MSCALE_Y];
dstVals[Matrix.MTRANS_Y] = srcVals[Matrix.MTRANS_Y];
dstVals[Matrix.MPERSP_0] = srcVals[Matrix.MPERSP_0];
dstVals[Matrix.MPERSP_1] = srcVals[Matrix.MPERSP_1];
dstVals[Matrix.MPERSP_2] = srcVals[Matrix.MPERSP_2];
dstMatrix.setValues(dstVals);
dstChart.getViewPortHandler().refresh(dstMatrix, dstChart, true);
}
}
public void syncCharts() {
if (dstCharts == null) {
return;
}
Matrix srcMatrix;
float[] srcVals = new float[9];
Matrix dstMatrix;
float[] dstVals = new float[9];
// get src chart translation matrix:
srcMatrix = srcChart.getViewPortHandler().getMatrixTouch();
srcMatrix.getValues(srcVals);
// apply X axis scaling and position to dst charts:
for (Chart dstChart : dstCharts) {
if (dstChart.getVisibility() == View.VISIBLE) {
dstMatrix = dstChart.getViewPortHandler().getMatrixTouch();
dstMatrix.getValues(dstVals);
dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
dstVals[Matrix.MSKEW_X] = srcVals[Matrix.MSKEW_X];
dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
dstVals[Matrix.MSKEW_Y] = srcVals[Matrix.MSKEW_Y];
dstVals[Matrix.MSCALE_Y] = srcVals[Matrix.MSCALE_Y];
dstVals[Matrix.MTRANS_Y] = srcVals[Matrix.MTRANS_Y];
dstVals[Matrix.MPERSP_0] = srcVals[Matrix.MPERSP_0];
dstVals[Matrix.MPERSP_1] = srcVals[Matrix.MPERSP_1];
dstVals[Matrix.MPERSP_2] = srcVals[Matrix.MPERSP_2];
dstMatrix.setValues(dstVals);
dstChart.getViewPortHandler().refresh(dstMatrix, dstChart, true);
}
}
}
public static float[] LoadGraphicsMatrix(Matrix matrix) {
float m[] = new float[16];
float v[] = new float[9];
matrix.getValues(v);
m[0] = v[Matrix.MSCALE_X]; //m.a;
m[1] = v[Matrix.MSKEW_X]; //m.b;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = v[Matrix.MSKEW_Y]; //m.c;
m[5] = v[Matrix.MSCALE_Y]; //m.d;
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = v[Matrix.MTRANS_X]; //m.tx;
m[13] = v[Matrix.MTRANS_Y]; //m.ty;
m[14] = 0.0f;
m[15] = 1.0f;
return m;
}
public void syncCharts() {
Matrix srcMatrix;
float[] srcVals = new float[9];
Matrix dstMatrix;
float[] dstVals = new float[9];
// get src chart translation matrix:
srcMatrix = srcChart.getViewPortHandler().getMatrixTouch();
srcMatrix.getValues(srcVals);
// apply X axis scaling and position to dst charts:
for (Chart dstChart : dstCharts) {
dstMatrix = dstChart.getViewPortHandler().getMatrixTouch();
dstMatrix.getValues(dstVals);
dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
dstVals[Matrix.MSKEW_X] = srcVals[Matrix.MSKEW_X];
dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
dstVals[Matrix.MSKEW_Y] = srcVals[Matrix.MSKEW_Y];
dstVals[Matrix.MSCALE_Y] = srcVals[Matrix.MSCALE_Y];
dstVals[Matrix.MTRANS_Y] = srcVals[Matrix.MTRANS_Y];
dstVals[Matrix.MPERSP_0] = srcVals[Matrix.MPERSP_0];
dstVals[Matrix.MPERSP_1] = srcVals[Matrix.MPERSP_1];
dstVals[Matrix.MPERSP_2] = srcVals[Matrix.MPERSP_2];
dstMatrix.setValues(dstVals);
dstChart.getViewPortHandler().refresh(dstMatrix, dstChart, true);
}
}
/**
* 计算图片的角度等属性
*
* @param model
* @return
*/
public StickerPropertyModel calculate(StickerPropertyModel model) {
float[] v = new float[9];
matrix.getValues(v);
// translation is simple
float tx = v[Matrix.MTRANS_X];
float ty = v[Matrix.MTRANS_Y];
Log.d(TAG, "tx : " + tx + " ty : " + ty);
// calculate real scale
float scalex = v[Matrix.MSCALE_X];
float skewy = v[Matrix.MSKEW_Y];
float rScale = (float) Math.sqrt(scalex * scalex + skewy * skewy);
Log.d(TAG, "rScale : " + rScale);
// calculate the degree of rotation
float rAngle = Math.round(Math.atan2(v[Matrix.MSKEW_X], v[Matrix.MSCALE_X]) * (180 / Math.PI));
Log.d(TAG, "rAngle : " + rAngle);
PointF localPointF = new PointF();
midDiagonalPoint(localPointF);
Log.d(TAG, " width : " + (mBitmap.getWidth() * rScale) + " height " + (mBitmap.getHeight() * rScale));
float minX = localPointF.x;
float minY = localPointF.y;
Log.d(TAG, "midX : " + minX + " midY : " + minY);
model.setDegree((float) Math.toRadians(rAngle));
//TODO 占屏幕百分比
float precentWidth = (mBitmap.getWidth() * rScale) / mScreenwidth;
model.setScaling(precentWidth);
model.setxLocation(minX / mScreenwidth);
model.setyLocation(minY / mScreenwidth);
model.setStickerId(stickerId);
if (isHorizonMirror) {
model.setHorizonMirror(1);
} else {
model.setHorizonMirror(2);
}
return model;
}
public BubblePropertyModel calculate(BubblePropertyModel model) {
float[] v = new float[9];
matrix.getValues(v);
// translation is simple
float tx = v[Matrix.MTRANS_X];
float ty = v[Matrix.MTRANS_Y];
Log.d(TAG, "tx : " + tx + " ty : " + ty);
// calculate real scale
float scalex = v[Matrix.MSCALE_X];
float skewy = v[Matrix.MSKEW_Y];
float rScale = (float) Math.sqrt(scalex * scalex + skewy * skewy);
Log.d(TAG, "rScale : " + rScale);
// calculate the degree of rotation
float rAngle = Math.round(Math.atan2(v[Matrix.MSKEW_X], v[Matrix.MSCALE_X]) * (180 / Math.PI));
Log.d(TAG, "rAngle : " + rAngle);
float minX = (dst_top.centerX() + dst_resize.centerX()) / 2;
float minY = (dst_top.centerY() + dst_resize.centerY()) / 2;
Log.d(TAG, "midX : " + minX + " midY : " + minY);
model.setDegree((float) Math.toRadians(rAngle));
model.setBubbleId(bubbleId);
//TODO 占屏幕百分比
float precentWidth = (mBitmap.getWidth() * rScale) / mScreenwidth;
model.setScaling(precentWidth);
Log.d(TAG, " x " + (minX / mScreenwidth) + " y " + (minY / mScreenwidth));
model.setxLocation(minX / mScreenwidth);
model.setyLocation(minY / mScreenwidth);
model.setText(mStr);
return model;
}
public static float[] LoadGraphicsMatrix(Matrix matrix) {
float m[] = new float[16];
float v[] = new float[9];
matrix.getValues(v);
m[0] = v[Matrix.MSCALE_X]; //m.a;
m[1] = v[Matrix.MSKEW_X]; //m.b;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = v[Matrix.MSKEW_Y]; //m.c;
m[5] = v[Matrix.MSCALE_Y]; //m.d;
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = v[Matrix.MTRANS_X]; //m.tx;
m[13] = v[Matrix.MTRANS_Y]; //m.ty;
m[14] = 0.0f;
m[15] = 1.0f;
return m;
}
/**
* 从 {@link Matrix} 中获取缩放比例
*/
public static float getMatrixScale(@NonNull Matrix matrix) {
synchronized (MATRIX_VALUES) {
matrix.getValues(MATRIX_VALUES);
final float scaleX = MATRIX_VALUES[Matrix.MSCALE_X];
final float skewY = MATRIX_VALUES[Matrix.MSKEW_Y];
return (float) Math.sqrt((float) Math.pow(scaleX, 2) + (float) Math.pow(skewY, 2));
}
}
public static float[] LoadGraphicsMatrix(Matrix matrix) {
float m[] = new float[16];
float v[] = new float[9];
matrix.getValues(v);
m[0] = v[Matrix.MSCALE_X]; //m.a;
m[1] = v[Matrix.MSKEW_X]; //m.b;
m[2] = 0.0f;
m[3] = 0.0f;
m[4] = v[Matrix.MSKEW_Y]; //m.c;
m[5] = v[Matrix.MSCALE_Y]; //m.d;
m[6] = 0.0f;
m[7] = 0.0f;
m[8] = 0.0f;
m[9] = 0.0f;
m[10] = 1.0f;
m[11] = 0.0f;
m[12] = v[Matrix.MTRANS_X]; //m.tx;
m[13] = v[Matrix.MTRANS_Y]; //m.ty;
m[14] = 0.0f;
m[15] = 1.0f;
return m;
}
/**
* スキューを考慮して実際の拡大縮小率を取得する
* @param mat
* @return
*/
public static float getScale(@NonNull final float[] mat) {
final float scaleX = mat[Matrix.MSCALE_X];
final float skewY = mat[Matrix.MSKEW_Y];
return (float) Math.sqrt(scaleX * scaleX + skewY * skewY);
}
public static float getYSkew(Matrix matrix){
float[] f = new float[9];
matrix.getValues(f);
return f[Matrix.MSKEW_Y];
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
float[] arrayOfFloat = new float[9];
matrix.getValues(arrayOfFloat);
float f1 = 0.0F * arrayOfFloat[0] + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f2 = 0.0F * arrayOfFloat[3] + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f3 = arrayOfFloat[0] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f4 = arrayOfFloat[3] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f5 = 0.0F * arrayOfFloat[0] + arrayOfFloat[1] * this.mBitmap.getHeight() + arrayOfFloat[2];
float f6 = 0.0F * arrayOfFloat[3] + arrayOfFloat[4] * this.mBitmap.getHeight() + arrayOfFloat[5];
float f7 = arrayOfFloat[0] * this.mBitmap.getWidth() + arrayOfFloat[1] * this.mBitmap.getHeight() + arrayOfFloat[2];
float f8 = arrayOfFloat[3] * this.mBitmap.getWidth() + arrayOfFloat[4] * this.mBitmap.getHeight() + arrayOfFloat[5];
canvas.save();
//先往文字上绘图
mBitmap = originBitmap.copy(Bitmap.Config.ARGB_8888, true);
canvasText.setBitmap(mBitmap);
canvasText.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
float left = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, dm);
float scalex = arrayOfFloat[Matrix.MSCALE_X];
float skewy = arrayOfFloat[Matrix.MSKEW_Y];
float rScale = (float) Math.sqrt(scalex * scalex + skewy * skewy);
float size = rScale * 0.75f * mDefultSize;
if (size > mMaxFontSize) {
mFontSize = mMaxFontSize;
} else if (size < mMinFontSize) {
mFontSize = mMinFontSize;
} else {
mFontSize = size;
}
mFontPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mFontSize, dm));
String[] texts = autoSplit(mStr, mFontPaint, mBitmap.getWidth() - left * 3);
float height = (texts.length * (baseline + fm.leading) + baseline);
float top = (mBitmap.getHeight() - height) / 2;
//基于底线开始画的
top += baseline;
for (String text : texts) {
if (TextUtils.isEmpty(text)) {
continue;
}
canvasText.drawText(text, mBitmap.getWidth() / 2, top, mFontPaint); //坐标以控件左上角为原点
top += baseline + fm.leading; //添加字体行间距
}
canvas.drawBitmap(mBitmap, matrix, null);
//删除在右上角
dst_delete.left = (int) (f3 - deleteBitmapWidth / 2);
dst_delete.right = (int) (f3 + deleteBitmapWidth / 2);
dst_delete.top = (int) (f4 - deleteBitmapHeight / 2);
dst_delete.bottom = (int) (f4 + deleteBitmapHeight / 2);
//拉伸等操作在右下角
dst_resize.left = (int) (f7 - resizeBitmapWidth / 2);
dst_resize.right = (int) (f7 + resizeBitmapWidth / 2);
dst_resize.top = (int) (f8 - resizeBitmapHeight / 2);
dst_resize.bottom = (int) (f8 + resizeBitmapHeight / 2);
//置顶在左上角
dst_top.left = (int) (f1 - topBitmapWidth / 2);
dst_top.right = (int) (f1 + topBitmapWidth / 2);
dst_top.top = (int) (f2 - topBitmapHeight / 2);
dst_top.bottom = (int) (f2 + topBitmapHeight / 2);
//水平镜像在右下角
// dst_flipV.left = (int) (f5 - topBitmapWidth / 2);
// dst_flipV.right = (int) (f5 + topBitmapWidth / 2);
// dst_flipV.top = (int) (f6 - topBitmapHeight / 2);
// dst_flipV.bottom = (int) (f6 + topBitmapHeight / 2);
if (isInEdit) {
canvas.drawLine(f1, f2, f3, f4, localPaint);
canvas.drawLine(f3, f4, f7, f8, localPaint);
canvas.drawLine(f5, f6, f7, f8, localPaint);
canvas.drawLine(f5, f6, f1, f2, localPaint);
canvas.drawBitmap(deleteBitmap, null, dst_delete, null);
canvas.drawBitmap(resizeBitmap, null, dst_resize, null);
// canvas.drawBitmap(flipVBitmap, null, dst_flipV, null);
canvas.drawBitmap(topBitmap, null, dst_top, null);
}
canvas.restore();
}
}