Matrix以及圖片適配計算相關
一、圖片縮放的計算方法
int mScreenWidth; // 螢幕寬度
int mScreenHeight; // 螢幕高度
int mImageWidth; // 圖片寬度
int mImgaeHeight; // 螢幕高度
float imgRatio = (float)mImageWidth / (float) mImgaeHeight;
float screenRatio = (float)mScreenWidth / (float) mScreenHeight;
1.1 圖片壓縮
目的:讓圖片等比壓縮到螢幕內,儘量不讓圖片尺寸超出螢幕,如果圖片剪裁
if (imgRatio < maxRatio) {
// 實際圖片寬高比小於最大尺寸寬高比時,說明圖片細長,期望圖片高度設定為最大高度,寬度等比壓縮;
// 含義同兩者的高度比數值小,圖片以高度比為基準等比壓縮
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
// 實際圖片寬高比大於最大尺寸寬高比時,說明圖片寬窄,期望寬度設定為最大寬度,高度等比壓縮;
// 含義同兩者的寬度比數值小,圖片以寬度比為基準等比壓縮
imgRatio = maxWidth / actualWidth;
ctualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
1.2 圖片放大
目的:讓圖片等比放大到超過螢幕尺寸,用於居中裁剪,類似centerCrop
if (imgRatio > maxRatio) {
// 高度為基準等比放大
actualWidth = (actualWidth * screenHeight) / actualHeight;
actualHeight = screenHeight;
} else if (imgRatio < maxRatio) {
// 寬度為基準等比放大
actualHeight = (screenWidth * actualHeight) / actualWidth;
actualWidth = screenWidth;
}
二、setScale,preScale和postScale的區別
1、setScale(sx,sy),首先會將該Matrix設定為對角矩陣,即相當於呼叫reset()方法,然後在設定該Matrix的MSCALE_X和MSCALE_Y直接設定為sx,sy的值
2、preScale(sx,sy),不會重置Matrix,而是直接與Matrix之前的MSCALE_X和MSCALE_Y值結合起來(相乘),M' = M * S(sx, sy)。
3、postScale(sx,sy),不會重置Matrix,而是直接與Matrix之前的MSCALE_X和MSCALE_Y值結合起來(相乘),M' = S(sx, sy) * M。
preScale和post都是與之前的Matrix結合起來,那它們之間又有什麼區別呢?
舉幾個例子測試下關於pre....和post....的區別:
對一個Matrix如下設定
1、pre....的執行順序
[java] view plaincopy
1. Matrix matrix=new Matrix();
2. float[] points=new float[]{10.0f,10.0f};
3.
4. matrix.preScale(2.0f, 3.0f);//
5. matrix.preTranslate(8.0f,7.0f);//
6. matrix.mapPoints(points);
7. Log.i("test", points[0]+"");
8. Log.i("test", points[1]+"");
結果為點座標為(36.0,51.0)
可以得出結論,進行變換的順序是先執行preTranslate(8.0f,7.0f),在執行的preScale(2.0f,3.0f)。這也是為什麼有的人比喻為pre...是向後生長的,即對於一個Matrix的設定中,
所有pre....是倒著向後執行的。
2、post...的執行順序
[java] view plaincopy
1. Matrix matrix=new Matrix();
2. float[] points=new float[]{10.0f,10.0f};
3.
4. matrix.postScale(2.0f, 3.0f);//
5. matrix.postTranslate(8.0f,7.0f);//
6. matrix.mapPoints(points);
7. Log.i("test", points[0]+"");
8. Log.i("test", points[1]+"");
結果為點座標為(28.0,37.0)
可以得出結論,進行變換的順序是先執行postScale(2.0f,3.0f),在執行的postTranslate(8.0f,7.0f)。這 也是為什麼有的人比喻為post...是向前生長的,即對於一個Matrix的設定中,所有post....是順著向前執行的。
3、當pre和post交替出現的執行順序
[java] view plaincopy
1. Matrix matrix=new Matrix();
2. float[] points=new float[]{10.0f,10.0f};
3.
4. matrix.postScale(2.0f, 3.0f);
5. matrix.preRotate(90);
6. matrix.mapPoints(points);
7. Log.i("test", points[0]+"");
8. Log.i("test", points[1]+"");
結果為點座標為(-20.0,30.0)
將pre...和post順序換一下
[java] view plaincopy
1. Matrix matrix=new Matrix();
2. float[] points=new float[]{10.0f,10.0f};
3.
4. matrix.preRotate(90);
5. matrix.postScale(2.0f, 3.0f);
6. matrix.mapPoints(points);
7. Log.i("test", points[0]+"");
8. Log.i("test", points[1]+"");
結果為點座標依舊為為(-20.0,30.0)
可見,總是pre先執行的。在看下面的:
[java] view plaincopy
1. Matrix matrix = new Matrix();
2. float[] points = new float[] { 10.0f, 10.0f };
3.
4. matrix.postScale(2.0f, 3.0f);// 第1步
5. matrix.preRotate(90);// 第2步
6. matrix.postTranslate(8.0f, 7.0f);// 第3步
7. matrix.preScale(1.5f, 2.5f);// 第4步
8. matrix.mapPoints(points);
9. Log.i("test", points[0] + "");
10. Log.i("test", points[1] + "");
結果為點座標依舊為為(-42.0,52.0)
經過前面的結論和推算,可以發現執行的順序是 4----2----1---3
在看下面的,增加了setScale的一段程式碼:
[java] view plaincopy
1. Matrix matrix = new Matrix();
2. float[] points = new float[] { 10.0f, 10.0f };
3.
4. matrix.postScale(2.0f, 3.0f);// 第1步
5. matrix.preRotate(90);// 第2步
6. matrix.setScale(1.4f, 2.6f);// 第3步
7. matrix.postTranslate(8.0f, 7.0f);// 第4步
8. matrix.preScale(1.5f, 2.5f);// 第5步
9. matrix.mapPoints(points);
10. Log.i("test", points[0] + "");
11. Log.i("test", points[1] + "");
結果為點座標依舊為為(29.0,72.0)
經過計算,可以發現,在第3步setScale之前的第1、2步根本就沒有用了,直接被第3步setScale覆蓋,在從第3開始執行的。
順序為2---1----3----5----4,因為2、1被覆蓋了,所以沒有效果,相當於直接執行3-----5----4
總結:最後可以得出結論,在對matrix該次變換之前的所有設定中,先檢測有沒有setScale,如果有,直接跳到setScale那一步開始 執行變換,然後在倒著執行下面所有的pre...變換,在順著執行所有post....的變換。所以在對Matrix變換設定的時候,一定要注意順序,不 同的順序,會有不同的結果。
marix來源:https://blog.csdn.net/u011122331/article/details/47149773