Matrix(二)那些沒啥關(guān)系的簡單操作

上章我們描述了Matrix的四個(gè)操作分別是:旋轉(zhuǎn)伟众,平移秽浇,縮放,扭曲
那么假設(shè)現(xiàn)在我們有一個(gè)需求:根據(jù)已有圖片生成這個(gè)分別使用了這四個(gè)操作的圖片弹惦。
那么思路很簡單,如果使用Matrix操作那么代碼應(yīng)該是這樣的:

public Bitmap postMatrix(Matrix matrix, Bitmap bitmap) {    
  Bitmap resource = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, false);   
  return resource;
}

根據(jù)上面的代碼我們重新生成了使用矩陣matrix的一張圖片悄但,而生成圖片的寬高仍然保持不變棠隐。那么問題來了,如果需要生成一張對應(yīng)變化寬高的一張圖片呢檐嚣?例如:

Matrix.png

下面逐一分析:

1.translate

平移操作的時(shí)候,先計(jì)算移除空白區(qū)域的圖片寬高助泽,生成新圖之后從負(fù)的偏移坐標(biāo)開始繪制圖片,則生成的圖片就是完整移動過后的圖片

 /**
     * 真實(shí)偏移,圖片寬高會根據(jù)圖片的偏移距離重新生成寬高
     *
     * @param bitmap,目標(biāo)圖片
     * @param preX,偏移X軸百分比
     * @param preY,偏移Y軸百分比
     * @param isRecycle,是否回收目標(biāo)圖
     * @return
     */
    public static Bitmap translate(Bitmap bitmap, float preX, float preY, boolean isRecycle) {
        Matrix matrix = new Matrix();
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int disX = (int) (width * preX);
        int disY = (int) (height * preY);
        matrix.postTranslate(disX, disY);
        Bitmap resource = Bitmap.createBitmap(bitmap.getWidth() - disX, bitmap.getHeight() - disY, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(resource);
//        canvas.drawColor(Color.BLACK);//模擬空白
        canvas.concat(matrix);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawBitmap(bitmap, -disX, -disY, paint);//從負(fù)偏移點(diǎn)開始畫嗡贺,那么如果進(jìn)行了translate操作隐解,那么圖片不會留白
        if (isRecycle) destroyBitmap(bitmap);
        return resource;
    }

效果圖如下:


translate.png

2.scale

和translate的差不多也需要重新計(jì)算寬高,但是需要保證繪制中心必須是新圖的中心诫睬。這樣等比放大的時(shí)候才不會缺失煞茫。

/**
     * 真實(shí)縮放,圖片寬高會根據(jù)圖片的縮放比例重新生成寬高
     *
     * @param bitmap,目標(biāo)
     * @param scale,縮放比例
     * @param isRecycle摄凡,是否回收目標(biāo)圖
     * @return
     */
    public static Bitmap scale(Bitmap bitmap, float scale, boolean isRecycle) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        int reWidth, reHeight;
        reWidth = (int) (width * scale);
        reHeight = (int) (height * scale);
        matrix.postScale(scale, scale);

        Bitmap resource = Bitmap.createBitmap(reWidth, reHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(resource);
        canvas.drawColor(Color.BLUE);
        canvas.concat(matrix);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawBitmap(bitmap, (float) ((reWidth - width) * 1.0 / 2), (float) ((reHeight - height) * 1.0 / 2), paint);
        if (isRecycle) destroyBitmap(bitmap);
        return resource;
    }

3.rotate

計(jì)算旋轉(zhuǎn)之后新圖的寬高续徽,這個(gè)還挺復(fù)雜的,之前查找了很多資料亲澡,最后還是問了底層的同事炸宵,搞到了一片描述這類問題的文章 【OpenCV】圖像幾何變換:旋轉(zhuǎn),縮放谷扣,斜切
文章里面關(guān)于的旋轉(zhuǎn)的數(shù)學(xué)模型如圖:

rotate原理.jpg

新圖的寬高則為(widthcos(a)+heightsin(a) , heightcos(a)+widthsin(a)) 這里 的 ‘a(chǎn)’ 指的是角度對應(yīng)的弧度哦土全!


    /**
     * 真實(shí)旋轉(zhuǎn),圖片寬高會根據(jù)圖片的旋轉(zhuǎn)角度重新生成寬高
     *
     * @param bitmap,目標(biāo)
     * @param degree,旋轉(zhuǎn)角度
     * @param isRecycle会涎,是否回收目標(biāo)圖
     * @return
     */
    public static Bitmap rotate(Bitmap bitmap, float degree, boolean isRecycle) {

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        int reWidth, reHeight;
//       以弧度為計(jì)算方式則新圖size為(width*cos(a)+height*sin(a), height*cos(a)+width*sin(a))
        double angle = (degree * Math.PI) / 180;//生成degree對應(yīng)的弧度
        double a = Math.abs(Math.sin(angle)), b = Math.abs(Math.cos(angle));
        reWidth = (int) (width * b + height * a);
        reHeight = (int) (height * b + width * a);
        Log.i(Tag, "width: " + width + "   reWidth   :" + reWidth);
        Log.i(Tag, "height: " + height + "   reHeight   :" + reHeight);
        Bitmap resource = Bitmap.createBitmap(reWidth, reHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(resource);
        canvas.drawColor(Color.BLACK);
        matrix.postRotate(degree, reWidth / 2, reHeight / 2);
        canvas.concat(matrix);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawBitmap(bitmap, (float) ((reWidth - width) * 1.0 / 2), (float) ((reHeight - height) * 1.0 / 2), paint);
        if (isRecycle) destroyBitmap(bitmap);
        return resource;
    }

效果如圖:


rotate.png

3.skew

額···這個(gè)還沒有寫的裹匙,這兩天坐火車做懵了,后期再補(bǔ)上來把末秃;如果有需要也可以參考 文章 《【OpenCV】圖像幾何變換:旋轉(zhuǎn)概页,縮放,斜切》中的 實(shí)踐:圖像放射變換(通過三點(diǎn)確定變換矩陣)

以上的demo地址: https://github.com/MartinBZDQSM/Matrix

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末练慕,一起剝皮案震驚了整個(gè)濱河市惰匙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铃将,老刑警劉巖项鬼,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異劲阎,居然都是意外死亡绘盟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門悯仙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來龄毡,“玉大人,你說我怎么就攤上這事锡垄÷倭悖” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵货岭,是天一觀的道長路操。 經(jīng)常有香客問我序攘,道長,這世上最難降的妖魔是什么寻拂? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任程奠,我火速辦了婚禮,結(jié)果婚禮上祭钉,老公的妹妹穿的比我還像新娘瞄沙。我一直安慰自己,他們只是感情好慌核,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布距境。 她就那樣靜靜地躺著,像睡著了一般垮卓。 火紅的嫁衣襯著肌膚如雪垫桂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天粟按,我揣著相機(jī)與錄音诬滩,去河邊找鬼。 笑死灭将,一個(gè)胖子當(dāng)著我的面吹牛疼鸟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庙曙,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼空镜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捌朴?” 一聲冷哼從身側(cè)響起吴攒,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砂蔽,沒想到半個(gè)月后洼怔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡察皇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年茴厉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片什荣。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖怀酷,靈堂內(nèi)的尸體忽然破棺而出稻爬,到底是詐尸還是另有隱情,我是刑警寧澤蜕依,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布桅锄,位于F島的核電站琉雳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏友瘤。R本人自食惡果不足惜翠肘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辫秧。 院中可真熱鬧束倍,春花似錦、人聲如沸盟戏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柿究。三九已至邮旷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝇摸,已是汗流浹背婶肩。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留貌夕,地道東北人狡孔。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像蜂嗽,于是被迫代替她去往敵國和親苗膝。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容