最近項(xiàng)目需求里有這么一個功能需求,在家庭平面圖(ImageView)上實(shí)時繪制一個小物件,并且能可視該物件的實(shí)時轉(zhuǎn)角。
思路:
解決方案一:兩層圖層,地圖是ImageView,頂圖是該物件,通過屬性動畫控制其旋轉(zhuǎn);
解決方案二:一層圖層,地圖是ImageView,直接在該ImageView上繪制該小物件Bitmap,并通過Mextra來旋轉(zhuǎn)物件。
問題:
方案一確實(shí)好用,但是有個問題,兩個圖層會把問題復(fù)雜化,最簡單的就是時時需要考慮統(tǒng)一坐標(biāo)。
下面說說方案二,很簡單。
在onDraw里通過旋轉(zhuǎn)矩陣的方式來旋轉(zhuǎn)Bitmap
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (pointX != 0 || pointY != 0) {
matrix.setRotate(0);
matrix.setRotate(degree);
Bitmap bitmap = Bitmap.createBitmap(robotBitmap, 0, 0, robotBitmapWidth, robotBitmapHeight, matrix, true);
canvas.drawBitmap(bitmap, pointX - bitmap.getWidth() / 2, pointY - bitmap.getHeight() / 2, mRobotBitmapPaint);
canvas.drawCircle(pointX, pointY, robotRadius, robotPaint); // 目標(biāo)點(diǎn)
}
}
至此問題已經(jīng)解決,下面是對createBitmap的解釋,時間緊的可以不看了。
解釋:
第一步:matrix.setRotate(0),把矩陣回歸到0度,因?yàn)榫仃囆D(zhuǎn)后就保持在最后一次旋轉(zhuǎn)的角度(在onDraw里面不要new Matrix()太頻繁,所以直接在初始化的時候new Matrix(),因此該步驟需要設(shè)置0度);
第二步:matrix.setRotate(degree),設(shè)置Bitmap要旋轉(zhuǎn)的角度,此處是°,不是弧度;
第三步:Bitmap bitmap = Bitmap.createBitmap(robotBitmap, 0, 0, robotBitmapWidth, robotBitmapHeight, matrix, true),通過一個bitmap創(chuàng)建一個新的Bitmap,不剪裁但旋轉(zhuǎn)該Bitmap;
第四步: canvas.drawBitmap(bitmap, pointX - bitmap.getWidth() / 2, pointY - bitmap.getHeight() / 2, mRobotBitmapPaint),繪制新的bitmap(pointX - bitmap.getWidth() / 2和pointY - bitmap.getHeight() / 2的作用是位圖的中心就是我們點(diǎn)擊的地方);
第五步:定位手指點(diǎn)擊的位置并畫出來,用于輔助查看要繪制的bitmap位置(因?yàn)槔L制點(diǎn)沒什么說,點(diǎn)哪里繪制哪里,bitmap的繪制就不一樣了,bitmap的繪制是從該圖的左上角開始繪制的,如下圖)

API
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
參數(shù)一:Bitmap,子bitmap,也就是原圖;
參數(shù)二:x,source中的第x列
參數(shù)三:y,source中的第y列,x,y決定了我們新的bitmap開始于source的第幾個像素
參數(shù)四:width,新的bitmap每一行的像素?cái)?shù)量
參數(shù)五:height,新的bitmap每一列的像素?cái)?shù)量
參數(shù)六:m,矩陣,可以理解為bitmap是相片,matrix是相框,相框怎么擺相片就怎么擺
參數(shù)七:filter,如果m不僅僅是移動,則最好修改為true,下面有圖參考
注意該異常:java.lang.IllegalArgumentException: x + width must be <= bitmap.width(),在我們給定的參數(shù)里,x+width<=source.width(), width is <= 0, or height is <= 0
參數(shù)四、五、六、七解釋
看圖知意,就是裁剪,如果不想裁剪,那么就按0,0,bitmapWidth,bitmapHeight設(shè)置

上圖的參數(shù)是
Bitmap bitmap = Bitmap.createBitmap(robotBitmap, 20, 20, robotBitmapWidth - 20, robotBitmapHeight - 20, matrix, true);
參數(shù)七 filter 解釋
直接看圖
圖一是原圖:

圖二是旋轉(zhuǎn)-10°,但filter為true

圖三是旋轉(zhuǎn)-10°,但filter為false

結(jié)語:
旋轉(zhuǎn)位圖其實(shí)是通過創(chuàng)建一個矩陣,旋轉(zhuǎn)該矩陣,用矩陣和原圖創(chuàng)建一個新的原圖副本(矩陣就是相框,副本就是相片),很簡單。