在onDraw中繪制可實(shí)時旋轉(zhuǎn)的bitmap

最近項(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的繪制是從該圖的左上角開始繪制的,如下圖)


picture1.png

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è)置

新圖像素起始點(diǎn)示例.png

上圖的參數(shù)是
Bitmap bitmap = Bitmap.createBitmap(robotBitmap, 20, 20, robotBitmapWidth - 20, robotBitmapHeight - 20, matrix, true);

參數(shù)七 filter 解釋

直接看圖
圖一是原圖:


原圖.jpg

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


filter為true.png

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

結(jié)語:

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容