Android中的圖片裁剪(三)之自定義裁剪工具

在上一篇文章中Android中的圖片裁剪(二)之開源項目介紹了一些優(yōu)秀的圖片裁剪開源項目,在我們實現(xiàn)自己的裁剪功能的時候媒殉,也可以看下這些開源項目的源碼外盯,看看大牛們都是怎么實現(xiàn)的捂襟。

createBitmap方法

首先要做圖片裁剪的功能,要先認識Bitmap壶硅,在這個類里面,有幾個方法可以幫助我們實現(xiàn)功能销斟。就比如下面這一個方法

/**
 * Returns an immutable bitmap from the specified subset of the source
 * bitmap. The new bitmap may be the same object as source, or a copy may
 * have been made. It is initialized with the same density as the original
 * bitmap.
 *...
 */
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)

好吧庐椒,方法注解太長,被我省略掉一些了蚂踊,但是用起來其實挺簡單的约谈,只要傳入指定的范圍,它就能生成一個新的位圖給你。(這里先說一句棱诱,圖片的裁剪功能其實做起來不難泼橘,要做好就挺麻煩的,在實際的工具開發(fā)中免不了要自定義View這樣的工作)迈勋,而這邊的范圍一般是一個可拖動的方框炬灭,點擊裁剪按鈕的時候生成我們需要的圖片。當然createBitmap方法還有很多其他重載實現(xiàn)靡菇,這里就不一一貼出來了重归。在具體實現(xiàn)的時候我們可以自定義兩個View

public class CropImageView extends ImageView {

    HighlightView hv;
    //...
 
}

class HighlightView {
    //...
}

這里只是簡單的提供一下思路,HighlightView用來表示裁剪框?qū)ο笙梅铮庋b裁剪框的一些信息啊鼻吮,比如寬高和觸摸狀態(tài)什么的。CropImageView繼承ImageView用來顯示圖片和處理觸摸事件较鼓,在觸摸事件中改變HighlightView的狀態(tài):

public boolean onTouchEvent(@NonNull MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
            //對觸摸點進行一些邏輯判斷椎木,比如摸到裁剪框的邊還是其他什么的
            int edge = hv.getHit(event.getX(), event.getY());
            //...
            //然后根據(jù)邏輯判斷結(jié)果設(shè)置裁剪框的狀態(tài)
            hv.setMode((edge == HighlightView.MOVE)
                        ? HighlightView.ModifyMode.Move
                        : HighlightView.ModifyMode.Grow);
            //...
        break;
            //...

啦啦啦,是不是說了跟沒說一樣笨腥,主要是具體實現(xiàn)起來真的挺麻煩的拓哺,貼那么多代碼出來也沒啥用,我自己都要看暈了脖母,總歸自己造輪子還是挺辛苦的士鸥,而且剛造出來也肯定有一些問題的,所以才有那句名言么谆级,不要重復(fù)造輪子烤礁,我覺得只要看懂源代碼的思路,然后根據(jù)需求肥照,在別人的輪子上進行改造脚仔,這樣就快的多啦。

Matrix的基本使用

一般呢舆绎,在裁剪的工具中鲤脏,在對圖片裁剪前,多可以對圖片進行一些縮放吕朵,平移猎醇,旋轉(zhuǎn)之類的操作,這些效果都是可以通過Matrix來實現(xiàn)的努溃,那這個類怎么用呢硫嘶。我們先看一下[官方文檔中Matrix](file:///D:/Android/sdk/docs/reference/android/graphics/Matrix.html)的介紹(自帶梯子) ,首先看一下它的官方定義:

**The Matrix class holds a 3x3 matrix for transforming coordinates. **

直譯過來呢梧税,就是一個轉(zhuǎn)換坐標的3x3矩陣沦疾,你妹啊称近,什么是3x3矩陣...我也不知道啊 ,高等數(shù)學(xué)這東西我早就扔了好么哮塞,不過不知道沒關(guān)系刨秆,面向?qū)ο竺矗蚁戎涝趺从镁涂梢粤顺固遥袝r間有閑情再去深究坛善。我們先主要看一下Matrix類里面,我們要用到的一些方法(補充說一下邻眷,這Matrix類是在graphics包下的眠屎,不要導(dǎo)成opengl包下的):

/**
 * Postconcats the matrix with the specified translation.
 * M' = T(dx, dy) * M
 */
public boolean postTranslate(float dx, float dy)

/**
 * Postconcats the matrix with the specified rotation.
 * M' = R(degrees) * M
 */
public boolean postRotate(float degrees)

好啦,畢竟是文檔找的到東西肆饶,我這里就只貼兩個方法出來改衩,看注解應(yīng)該很容易理解方法的使用,第一個方法就是對矩陣進行左乘T(dx, dy)驯镊,第二個方法就是對矩陣左乘R(degrees)葫督,通過源碼我們可以看到,方法里面通過jni調(diào)用lib層用c板惑,c++實現(xiàn)運算轉(zhuǎn)換的橄镜。反正直白點講,在對它進行圖片變換的時候冯乘,第一個方法就是平移圖片洽胶,第二個方法就是旋轉(zhuǎn)圖片,啦啦啦裆馒,其他方法大家可以自行查找文檔姊氓,問題都不大。

圖片的平移喷好,縮放翔横,旋轉(zhuǎn)

通過重寫View或者Activity的onTouch事件來進行圖片的平移,縮放和旋轉(zhuǎn)會比較方便梗搅,這里我們要先做一些初始化工作禾唁,比如獲取圖片之類的,一般我們將圖片的大小控制在手機內(nèi)存的1/8无切,防止OOM和卡頓蟀俊,然后就是在onTouch事件里做具體實現(xiàn):

public boolean onTouch(View v, MotionEvent event)
{

    switch (event.getAction() & MotionEvent.ACTION_MASK)
    {
        // 主點按下
        case MotionEvent.ACTION_DOWN:
            cachMatrix.set(matrix);//用來變化的矩陣
            prev.set(event.getX(), event.getY());
            mode = DRAG;
            break;
        //...
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG)//拖動
            {
                matrix.set(cachMatrix);
                matrix.postTranslate(event.getX() - prev.x, event.getY() - prev.y);
            }
            else if (mode == ZOOM)//縮放
            {
                float newDist = spacing(event);
                if (newDist > 10f)
                {
                    matrix.set(cachMatrix);
                    float tScale = newDist / dist;
                    matrix.postScale(tScale, tScale, mid.x, mid.y);
                }
            }
            break;
    }
    imgView.setImageMatrix(matrix);
    //...
    return true;
}

代碼就放了部分上去,主要說明一下思路订雾,當然在將這些功能和裁剪進行合并的時候,是要對裁剪框的位置再進行計算的,比如因為對圖片縮放了矛洞,所以再返回剪裁框大小的時候是要乘上縮放值的洼哎。

public Rect getScaledCropRect(float scale) {
    return new Rect((int) (cropRect.left * scale), (int) (cropRect.top * scale),
            (int) (cropRect.right * scale), (int) (cropRect.bottom * scale));
}

總結(jié)

圖片的裁剪就先寫到這里烫映,主要介紹了一些關(guān)鍵方法和整體的實現(xiàn)思路,后面有時間的話噩峦,我會把代碼整理后發(fā)布到github上去的锭沟,到時候再來補鏈接。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末识补,一起剝皮案震驚了整個濱河市族淮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凭涂,老刑警劉巖祝辣,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異切油,居然都是意外死亡蝙斜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門澎胡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孕荠,“玉大人,你說我怎么就攤上這事攻谁≈晌椋” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵戚宦,是天一觀的道長个曙。 經(jīng)常有香客問我,道長阁苞,這世上最難降的妖魔是什么困檩? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮那槽,結(jié)果婚禮上悼沿,老公的妹妹穿的比我還像新娘。我一直安慰自己骚灸,他們只是感情好糟趾,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甚牲,像睡著了一般义郑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丈钙,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天非驮,我揣著相機與錄音,去河邊找鬼雏赦。 笑死劫笙,一個胖子當著我的面吹牛芙扎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播填大,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼戒洼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了允华?” 一聲冷哼從身側(cè)響起圈浇,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎靴寂,沒想到半個月后磷蜀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡榨汤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年蠕搜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片收壕。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡妓灌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜜宪,到底是詐尸還是另有隱情虫埂,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布圃验,位于F島的核電站掉伏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澳窑。R本人自食惡果不足惜斧散,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摊聋。 院中可真熱鬧鸡捐,春花似錦、人聲如沸麻裁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煎源。三九已至色迂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間手销,已是汗流浹背歇僧。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锋拖,地道東北人诈悍。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓埂淮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親写隶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

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