Matrix與圖像變換

在Android中我們經常需要在屏幕上顯示變換的圖像,比如顯示一張旋轉的圖像,或者一張圖片做點斜切,產生類似於透視的效果。這些都需要依賴於Matrix類。其中用得最多的就是
Bitmap類的
public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
以及Canvas類的
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)
這兩個方法了。

我們寫個程序比較一下二者的區別。


public MyView(Context context , AttributeSet set)
{
super(context , set);
// 獲得位圖
bitmap = ((BitmapDrawable) context.getResources().getDrawable(
R.drawable.a)).getBitmap();
// 獲得位圖寬
width = bitmap.getWidth();
// 獲得位圖高
height = bitmap.getHeight();
// 使當前視圖獲得焦點
this.setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
// 重置Matrix
matrix.reset();
if (!isScale)
{
// 旋轉Matrix
matrix.setSkew(sx, 0);
Log.d("matrix", "matrix is : "+matrix);
}
else
{
// 縮放Matrix
matrix.setScale(scale, scale);
}
// 根據原始位圖和Matrix創建新圖片
Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width/2, height/2,
matrix, true); //(0)
Log.d("matrix", "original (w,h)"+width+","+height);
Log.d("matrix", "(w,h)"+bitmap2.getWidth()+","+bitmap2.getHeight());
// 繪製新位圖
//canvas.drawBitmap(bitmap, matrix, null); //(1)
canvas.drawBitmap(bitmap2,0,0,null); //(2)
}
以上代碼,當我們啓用(1)處的代碼繪製圖像時,繪製的原始圖像bitmap,但是在繪製時使用matrix對圖像進行了變換。此時如果matrix是

1000.110001

則生成的圖像如下圖
這裏寫圖片描述
可以看到整個圖像自上而下往左傾斜。這個很容易通過數學來解釋。因爲屏幕座標系如圖所示,x軸向右,y軸向下,而我們上面matrix矩陣的m12 元素有個-0.1的值。那也就是說原來圖像上(x,y)上的點會被繪製到(x-0.1y,y)位置處。所以導致隨着y的增大(圖像由第一行往下),圖像上的點的橫向位置都比原始位置更靠左(x座標更小),於是就形成了上述效果。圖像左邊緣已經超出屏幕範圍了。

使用同樣的矩陣,如果我們啓用(2)出的代碼,也就是說我們在生成bitmap圖像的時候就對圖像做變換,而在繪製的時候按照圖像本身原原本本地繪製。我們看到的效果如下圖
這裏寫圖片描述
可以看到效果和前次類似,但又不完全一樣。
類似是指圖像從上往下還是向左傾斜。這表明在drawBitmap和createBitmap時matrix啓的作用是相同的,都是將像素點的座標構成的列向量左乘矩陣matrix,以得到新的位置。
不一樣的地方在於,圖像的左邊緣不超出屏幕了。這是因爲此時上次超出屏幕的部分現在已經是圖像的一部分,如果此時查看圖像的大小可以看到圖像已經由300*294變成了329*294大小了,而329正是300+0.1*294得到的。此時圖像的原點已經不再是白色區域的左上角了,而是新補上去的黑色區域的左上角,所以圖像能夠完全顯示。

總結,圖像變換時matrix的作用在於改變像素的位置,牢記這一點以後使用matrix才能夠正確地設置各個位置的參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章