關(guān)于ImageView中Matrix的方法setScale()縮放處理

我們經(jīng)常在項目中使用ImageView的scaleType來設(shè)置顯示圖片的顯示方式诫惭,其中有一種type是矩陣變化matrix方式我們可能在項目中會相對少用毛雇,具體matrix的使用方式锭吨,不是文章的重點阿蝶,可以自行g(shù)oogle或者參考一下其他同學(xué)寫的文章,主要我們講一下Matrix.setScale()方式在使用過程中踩的坑饼丘,同樣可以引申到Matrix的其他方法

參考文章

android matrix 最全方法詳解與進階(完整篇)

基本方法介紹

接下來我們簡單介紹一下Matrix類常用的幾種變化:

  • setTranslate(float dx,float dy):控制Matrix進行平移夸浅;
  • setSkew(float kx,float ky,float px,float py):控制Matrix以px,py為軸心進行傾斜仑最,kx,ky為X,Y方向上的傾斜距離;
  • setRotate(float degress):控制Matrix進行旋轉(zhuǎn)帆喇,degress控制旋轉(zhuǎn)的角度警医;
  • setRorate(float degress,float px,float py):設(shè)置以px,py為軸心進行旋轉(zhuǎn),degress控制旋轉(zhuǎn)角度番枚;
  • setScale(float sx,float sy):設(shè)置Matrix進行縮放法严,sx,sy控制X,Y方向上的縮放比例;
  • setScale(float sx,float sy,float px,float py):設(shè)置Matrix以px,py為軸心進行縮放(此處有坑)葫笼,sx,sy控制X,Y方向上的縮放比例深啤;

當(dāng)然這里只是set方法,還有相應(yīng)的preXXX()postXXX()方法路星,其中的區(qū)別就是pre和post和執(zhí)行的順序有關(guān)系溯街,set開頭的方法是直接清除之前Matrix內(nèi)的所有變化,重新設(shè)置一次洋丐。

  • set是直接設(shè)置Matrix的值呈昔,每調(diào)用一次,之前Matrix內(nèi)的所有變化都重置友绝,整個Matrix的數(shù)組都會變掉
  • post是后乘堤尾,當(dāng)前的矩陣乘以參數(shù)給出的矩陣∏停可以連續(xù)多次使用post郭宝,來完成所需的整個變換
  • pre是前乘辞槐,參數(shù)給出的矩陣乘以當(dāng)前的矩陣。所以操作是在當(dāng)前矩陣的最前面發(fā)生的粘室。

我們知道m(xù)atrix實際上是一個3x3的矩陣榄檬,根據(jù)線性代數(shù)里面的知識,矩陣相乘衔统,前乘和后乘得到的結(jié)果是不一樣的鹿榜,所以我們做的矩陣任何的變化(平移、縮放锦爵、旋轉(zhuǎn)等)本質(zhì)上都是對matrix矩陣進行操作舱殿,理解了這一點,對我們后面的踩坑有莫大的幫助

踩坑

這里講一下在上面setScale(float sx,float sy,float px,float py)在實際應(yīng)用中的坑险掀,我們先看下Android注釋是怎么解釋這個方法的

Set the matrix to scale by sx and sy, with a pivot point at (px, py).The pivot point is the coordinate that should remain unchanged by the specified transformation.

這里什么意思呢怀薛?就是設(shè)置matrix根據(jù)sx和sy的值進行縮放,那么px和py是什么鬼呢迷郑?網(wǎng)絡(luò)上很多解釋是解釋成中心點,在這個中心點的基礎(chǔ)上進行縮放创倔,其實不然嗡害,后面我們會講到這里為什么會有坑,如果你把這兩個參數(shù)當(dāng)成縮放的中心點來看的話畦攘,在實際測試過程中你會發(fā)現(xiàn)圖片并不是在當(dāng)前中心點縮放霸妹,在縮放的同時,位置還會進行偏移(這里行為跟postScale(float sx,float sy,float px,float py)中的px與py不一致知押,post行為是真的以此處為中心點進行縮放)叹螟。這里為什么會這樣呢?坑了我好久台盯,不死心罢绽,覺得一定有什么貓膩,所以最好的方式静盅,就是看看他的源碼良价,看下到底是什么原因?qū)е碌?/p>

先看下Matrix.java

    /**
     * Set the matrix to scale by sx and sy, with a pivot point at (px, py).
     * The pivot point is the coordinate that should remain unchanged by the
     * specified transformation.
     */
    public void setScale(float sx, float sy, float px, float py) {
        native_setScale(native_instance, sx, sy, px, py);
    }

納尼?調(diào)用了native_setScale方法蒿叠,可能很多人看到這一步需要去看native層的方法就放棄明垢,但是沒有什么能難倒攻城獅,不急市咽,我們接著往下看

    private static native void native_setScale(int native_object,
                                        float sx, float sy, float px, float py);

根據(jù)一些jni的知識痊银,我們知道在native層的代碼肯定會有一個native_setScale的方法與之對應(yīng),所以我們需要去找到該native層的實現(xiàn)方法施绎,看看他的代碼溯革。那么接下來我們?nèi)ツ睦镎夷卣晟靠赡芎芏嗤瑢W(xué)會想到去下源碼,可是源碼何其多鬓照,網(wǎng)絡(luò)情況良好的情況下個幾天都是正常的熔酷,這里我推薦一個網(wǎng)站androidxref,這里面有你所需要的各個版本的源碼豺裆,并且可以根據(jù)查詢條件快速查找拒秘,查找也是非常快的臭猜。最后我們在Matrix.cpp中找到了

    {"native_setScale","(IFFFF)V", (void*) SkMatrixGlue::setScale__FFFF},

// 對應(yīng)的方法
    static void setScale__FFFF(JNIEnv* env, jobject clazz, SkMatrix* obj, jfloat sx, jfloat sy, jfloat px, jfloat py) {
        SkScalar sx_ = SkFloatToScalar(sx);
        SkScalar sy_ = SkFloatToScalar(sy);
        SkScalar px_ = SkFloatToScalar(px);
        SkScalar py_ = SkFloatToScalar(py);
        obj->setScale(sx_, sy_, px_, py_);
    }

最后我們看一下obj->setScale(sx_, sy_, px_, py_);的實現(xiàn)

    void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
       if (SK_Scalar1 == sx && SK_Scalar1 == sy) {
           this->reset();
       } else {
           fMat[kMScaleX] = sx;
           fMat[kMScaleY] = sy;
           fMat[kMTransX] = px - SkScalarMul(sx, px);
           fMat[kMTransY] = py - SkScalarMul(sy, py);
           fMat[kMPersp2] = kMatrix22Elem;
   
           fMat[kMSkewX]  = fMat[kMSkewY] =
           fMat[kMPersp0] = fMat[kMPersp1] = 0;
   
           this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask);
       }
   }

這里我們看到實際上不當(dāng)當(dāng)進行了縮放操作躺酒,還進行了平移操作,所以我們實際進行縮放的時候蔑歌,還伴隨著平移操作羹应,實際上這里最后換算成的算法是fMat[kMTransX] = px - sx * px;。所以想要保持在縮放過程中不進行平移次屠,那么我們需要改造一下算法px = fMat[kMTransX]/(1-sx)园匹,那么有人會問,那我怎么能提前知道fMat[kMTransX]的值呢劫灶,這里就要在每次縮放操作前裸违,根據(jù)當(dāng)前需要縮放的比例,預(yù)測量出值本昏,這里就不介紹怎么預(yù)測量供汛,相信機智的小伙伴肯定已經(jīng)有想法了~好了,這里就講到這里涌穆,有問題請留言怔昨,我會及時回復(fù),歡迎交流~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宿稀,一起剝皮案震驚了整個濱河市趁舀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌原叮,老刑警劉巖赫编,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奋隶,居然都是意外死亡擂送,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門唯欣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嘹吨,“玉大人,你說我怎么就攤上這事境氢◇翱剑” “怎么了碰纬?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長问芬。 經(jīng)常有香客問我悦析,道長,這世上最難降的妖魔是什么此衅? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任强戴,我火速辦了婚禮,結(jié)果婚禮上挡鞍,老公的妹妹穿的比我還像新娘骑歹。我一直安慰自己,他們只是感情好墨微,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布道媚。 她就那樣靜靜地躺著,像睡著了一般翘县。 火紅的嫁衣襯著肌膚如雪最域。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天锈麸,我揣著相機與錄音羡宙,去河邊找鬼。 笑死掐隐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钞馁。 我是一名探鬼主播虑省,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼僧凰!你這毒婦竟也來了探颈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤训措,失蹤者是張志新(化名)和其女友劉穎伪节,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绩鸣,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡怀大,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呀闻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片化借。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捡多,靈堂內(nèi)的尸體忽然破棺而出蓖康,到底是詐尸還是另有隱情铐炫,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布蒜焊,位于F島的核電站倒信,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏泳梆。R本人自食惡果不足惜鳖悠,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸭丛。 院中可真熱鬧竞穷,春花似錦、人聲如沸鳞溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熟菲。三九已至看政,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抄罕,已是汗流浹背允蚣。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呆贿,地道東北人嚷兔。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像做入,于是被迫代替她去往敵國和親冒晰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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

  • CSDN博客 img cquwentao android matrix 最全方法詳解與進階(完整篇) 發(fā)表于201...
    北風(fēng)知我意閱讀 4,820評論 0 0
  • 一竟块、矩陣的定義 二壶运、矩陣與矩陣的乘法 矩陣的乘法滿足以下運算律:結(jié)合律,分配律,但是矩陣乘法不滿足交換律。更詳細(xì)的...
    Calllanna閱讀 2,775評論 0 1
  • 1浪秘、引子 筆者剛開始工作時蒋情,做的第一個模塊是手機中的launcher,launcher可自由選擇滑屏效果耸携,甚至還有...
    某昆閱讀 3,837評論 0 6
  • 本文行文目錄:一棵癣、Camera與Matrix初步認(rèn)識二、Camera與Matrix旋轉(zhuǎn)效果拆分介紹三夺衍、Camera...
    zhangke3016閱讀 17,782評論 18 136
  • 1.早上看第五單元單詞視頻 2.去老師辦公室實習(xí)一天 *當(dāng)你探測到未知領(lǐng)域的時候就會特別興奮浙巫,如果覺得還能學(xué)到東西...
    追咪閱讀 182評論 0 0