2014年10月11日 星期六

Canvas coordinate system

    近加新功能的時,碰到一個在Canvas上座標系統認知上有所不同的地方;一般我們會用 Canvas.drawBitmap(Bitmap, 10, 10, Paint)把一張圖畫在(0,0)的位置,當然這個(0,0)不預期是整個device的(0,0),而是根據View最後被擺放的位置,例如某View被Layout在(100, 100),而Canvas.drawBitmap(Bitmap, 10, 10, Paint)則會畫在螢幕(110,110)的地方。

到目前為止都沒有錯誤,但如果translation的方式是用Matrix,而你的code可能會變成

Matrix matrix = new Matrix();
matrix.postTranslate(10, 10);
canvas.setMatrix(matrix);
Canvas.drawBitmap(Bitmap, matrix, Paint);

此時畫出來的結果就還是會在(10, 10)。原本猜想是忘記apply原本canvas的matrix所致,所以改成

Matrix matrix = new Matrix(canvas.getMatrix());
matrix.postTranslate(10, 10);
canvas.setMatrix(matrix);
Canvas.drawBitmap(Bitmap, matrix, Paint);

結果還是(10,10)!結果不小心喵到有Method叫Canvas.concat()。後來改成:

Matrix matrix = new Matrix(canvas.getMatrix());
matrix.postTranslate(10, 10);
canvas.concat(matrix);
Canvas.drawBitmap(Bitmap, matrix, Paint);

最後就成功的畫在(110,110)的位置。百思不得其解的是:

Matrix matrix = new Matrix(canvas.getMatrix()) 應該會等於 canvas.concat(matrix)

因為都會Apply原本Canvas裡面的Matrix參數,於是乎就去看了一下底層的source code

 public void concat(Matrix matrix) {
     native_concat(matrix.native_instance);
 }

 public void setMatrix(Matrix matrix) {
          
matrix == null ? 0 : matrix.native_instance);
 }

看來還要追到NDK那層,不過看起來兩種設定Matrix的方式有些出入,就等未來有空再往底層看了。





沒有留言:

張貼留言