2012-09-04 40 views
4

的圖像由一個矩陣縮放:如何獲得任意矩陣的縮放值?

Matrix matrix = new Matrix(); 
matrix.postScale(...); 
matrix.postTranslate(...); 
matrix.postRotate(...); 
... 

希望將縮放圖像將不小於原來的一半,所以總變焦不應小於0.5。

但如何做到這一點?我試圖讓矩陣的第一個值進行檢查:

float pendingZoom = 0.6f; 

float[] values = new float[9]; 
Matrix.getValues(values); 
float scalex = values[Matrix.MSCALE_X]; 

然後:

if(scalex<0.5) { 
    pendingZoom = pendingZoom * (0.5f/scalex); 
} 

不幸的是,它不工作有時。如果圖像已旋轉,則scalex可能爲負數,pendingZoom也將爲負數。

如何正確執行此操作?


UPDATE

我剛剛發現了values[Matrix.MSCALE_X]不是realiable變焦值。我用它來計算矩形的新寬度,這是不正確的。

相反,我試圖通過矩陣兩點圖,並計算兩個距離:

PointF newP1 = mapPoint(matrix, new PointF(0, 0)); 
PointF newP2 = mapPoint(matrix, new PointF(width, 0)); 
float scale = calcDistance(newP1, newP2)/width; 

我現在就可以得到正確的scale值。但我不確定這是否是最佳解決方案。

+1

有誰知道爲什麼旋轉後矩陣是不同的?似乎在postRotate之後「scale x」不在Matrix.MSCALE_X索引(它是0)下,但是在1索引下。 –

+0

將矩陣分解爲平移,縮放和旋轉解釋[here](http://math.stackexchange.com/questions/13150/)。 – ulatekh

回答

7
float scalex = values[Matrix.MSCALE_X]; 
    float skewy = values[Matrix.MSKEW_Y]; 
    float scale = (float) Math.sqrt(scalex * scalex + skewy * skewy); 

這個解決方案看起來比較簡單,但我認爲你的清晰度和清晰度都比這個清晰得多。

+0

請看我更新的問題:) – Freewind

+1

@Freewind我認爲你的解決方案非常棒。很清楚它是如何工作的,任何解決這個問題的方法都需要提取平方根,所以它不能做得更快。我只有建議是不要在負責滾動的代碼中執行新的PointF(),因爲它會觸發垃圾回收器,並且對滾動性能不利。改用一些預先創建的PointF成員變量。 –

+0

更新我的答案只是爲了提供另一種解決方案 –

0

你可以只取絕對值

Math.abs(mMatrixValues[Matrix.MSCALE_X]);