Canvas 對繪制的輔助--范圍裁切與幾何變換
1.范圍裁切
范圍裁切有兩個方法:clipRect(),clipPath()
范圍裁切就是將將畫布裁切成指定的形狀大小今瀑,然后在裁切后的畫布上作圖捞稿。
1.1 clipRect()
這里直接進行矩形裁切!
例:
Cavase.clipRect(left,top,right,bottom);
1.2 clipPath()
這里用戶可以按照自己指定的圖形進裁切嗤详!
例:
canvas.save();
canvas.clipPath(path1);
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
canvas.save();
canvas.clipPath(path2);
canvas.drawBitmap(bitmap, point2.x, point2.y, paint);
canvas.restore();
2.幾何變換
幾何變換大致分為三類
? 使用canvas來做常見的二維變換
? 使用matrix來做常見和不常見的二維變換
? 使用camera來做三維變換
2.1 使用canvas來做常見的二維變換
2.1.1 使用canvas.translate(float dx,float dy)平移
參數dx和dy表示橫向和縱向的位移。
這個時候可以簡單理解為將物體的左上頂點平移水平平移x距離扣汪,豎直方向平移y距離断楷。
2.1.2 Canvas.rotate(float degrees,float px,float py)旋轉
degrees為旋轉角度(旋轉方向為順時針),px崭别,py為旋轉軸心。
例:
canvas.save();
canvas.rotate(45, centerX, centerY);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
2.1.3 canvas.scale(float sx,float sy,float px,float py) 縮放
參數 sx sy 為橫向縮放和縱向縮放倍數恐锣,px茅主,py是縮放軸心。
例:
canvas.save();
canvas.scale(1.3f, 1.3f, x + bitmapWidth / 2, y + bitmapHeight / 2);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
2.1.4 canvas.skew(float sx,float sy,float sy)錯切
參數:sx sy 為x方向和y方向錯切的錯切系數
例:
canvas.save();
canvas.skew(0, 0.5f);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
2.2 使用Matrix 做變換
2.2.1 使用Matrix 做常見變換
1.創(chuàng)建Matrix對象
2.調用Matrix的 pre/postTranslate/Rotate/Scale/Skew() 方法來設置幾何變換
3.使用Canvas.setMatrix(matrix)或Canvas.concat(matrix)來將幾何變換應用到Canvas中土榴。
Canvas.setMatrix(matrix) 和 Canvas.concat(matrix) 方法區(qū)別
? Canvas.setMatrix(matrix):用 Matrix 直接替換 Canvas 當前的變換矩陣诀姚,即拋棄 Canvas 當前的變換,改用 Matrix 的變換(注:不同的系統(tǒng)中 setMatrix(matrix) 的行為可能不一致玷禽,所以還是盡量用 concat(matrix) 吧)赫段;
? Canvas.concat(matrix):用 Canvas 當前的變換矩陣和 Matrix 相乘,即基于 Canvas 當前的變換矢赁,疊加上 Matrix 中的變換糯笙。
2.2.2使用Matrix 來做自定義變換
2.2.2.1 Matrix.setPolyToPoly(float[] src,int srcIndex,float[] dst,int dstIndex,int pointCount)用點對點映射的方式設置變換。
poly 就是「多」的意思撩银。setPolyToPoly() 的作用是通過多點的映射的方式來直接設置變換给涕。「多點映射」的意思就是把指定的點移動到給出的位置额获,從而發(fā)生形變够庙。例如:(0, 0) -> (100, 100) 表示把 (0, 0) 位置的像素移動到 (100, 100) 的位置,這個是單點的映射抄邀,單點映射可以實現(xiàn)平移耘眨。而多點的映射,就可以讓繪制內容任意地扭曲境肾。
例:
Matrix matrix = new Matrix();
float pointsSrc = {left, top, right, top, left, bottom, right, bottom};
float pointsDst = {left - 10, top + 50, right + 120, top - 90, left + 20, bottom + 30, right + 20, bottom + 60};
...
matrix.reset();
matrix.setPolyToPoly(pointsSrc, 0, pointsDst, 0, 4);
canvas.save();
canvas.concat(matrix);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
參數里剔难,src 和 dst 是源點集合目標點集;srcIndex 和 dstIndex 是第一個點的偏移准夷;pointCount 是采集的點的個數(個數不能大于 4钥飞,因為大于 4 個點就無法計算變換了)。
注:使用此方法最好關閉硬件加速衫嵌,單純是drawBitmap可以不用關读宙,其他必須關,不然效果不理想
2.3 使用Camera 做三維變換 Camera 的變化有 旋轉楔绞,平移结闸,移動相機
2.3.1 Camera.rorate*() 三維旋轉
rorateX(deg)沿X軸旋轉
rorateY(deg)沿Y軸旋轉
rorateZ(deg)沿Z軸旋轉
Rorate(x,y,z)沿X,Y,Z軸旋轉
2.3.2 Camera.translate(float x,float y,float z)移動
2.3.3 Camera.setLocation(x,y,z)設置虛擬相機的位置
這里唇兑,設置Camera虛擬相機位置的參數不是像素,是英寸桦锄。
這種設計源自 Android 底層的圖像引擎 Skia 扎附。在 Skia 中,Camera 的位置單位是英寸结耀,英寸和像素的換算單位在 Skia 中被寫死為了 72 像素留夜,而 Android 中把這個換算單位照搬了過來。是的图甜,它碍粥。寫。死黑毅。了嚼摩。
在 Camera 中,相機的默認位置是 (0, 0, -8)(英寸)矿瘦。8 x 72 = 576枕面,所以它的默認位置是 (0, 0, -576)(像素)。
在Camera.setLocation(x,y,z)中缚去,x與y一般不會改動潮秘!
如果繪制的內容過大,當它翻轉起來的時候病游,就有可能出現(xiàn)圖像投影過大的「糊臉」效果唇跨。而且由于換算單位被寫死成了 72 像素,而不是和設備 dpi 相關的衬衬,所以在像素越大的手機上买猖,這種「糊臉」效果會越明顯。
使用Camera.setLocation(0滋尉,0玉控,x)可以修復這個問題