android圖庫中選擇照片然後裁剪,完爆目前各種所謂的教學,看不懂你打我。

前陣子是打算做一個選擇相冊裏的照片裁剪並上傳的功能。
然後我就看了很多教程,看了網上很多文章,發現這些人都是在抄來抄去,裏面很多細節和思路都沒有寫清楚。真是誤人子弟又操蛋。
所以自己琢磨了一下代碼,然後寫下這篇文章。
首先是說思路:
拍照這個功能先不說,先說選圖片裁剪然後上傳的思路。
1.首先要選定一個路徑,然後在這個路徑下面建立一個空白文件;
2.然後選擇一張相冊裏的圖,把這個圖的內容原封不動的複製到這個新建的空白文件中。
3.然後打開裁剪程序,裁剪這個新建的文件,再把裁剪好的文件重新輸出到這個新建的文件中,對,就是替換。
4.上傳這個新建的文件。
現在一步一步的說。

1.選定一個路徑,新建一個空白文件。這個softtime是我APP的名字,最開始的時候我建立的文件總是找不到,後來發現要下載一個文件瀏覽器才能看見,系統把它隱藏了。爲此糾結了好久。這裏面有個函數 System.currenTimeMillis()是獲得系統當前時間毫秒數。
關於Environment.getExternalStorageDirectory(),這個函數其實就是獲得你手機SD卡的根目錄。
(注意:這裏currentImageFile 是建的一個全局變量。方便以後調用。)
File dir = new File(Environment.getExternalStorageDirectory(), "pictures/softtime");//存儲路徑
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                currentImageFile = new File(dir, System.currentTimeMillis()+".jpg");//路徑+名稱 = 存儲文件具體位置
                //文件不存在的話則新建
                if (!currentImageFile.exists()) {
                    try {
                        currentImageFile.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

2.選擇相冊裏的圖,然後輸出到這個新建的文件。(注意看一下注釋,我認真的寫的註釋)
//這個Intent是準備打開相冊,網上有多種方法,但是隻有這樣寫是管用的。其他的不管用,別信。
Intent intentGet = new Intent("android.intent.action.GET_CONTENT");  
//下面這裏其實是設置給那個圖庫應用看的,這裏可以限定圖庫打開的文件是什麼,現在設置的就是圖像文件。
intentGet.setType("image/*");
//下面這兩行其實並不重要,意義也不明,但是沒有卻不行。所以就直接照樣子寫下來就行。
intentGet.putExtra("crop",true);
intentGet.putExtra("scale",true);
//最重要的就是下面這行代碼了。一會詳細說。
intentGet.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(currentImageFile));
//這個也很重要,一會詳細說。
startActivityForResult(intentGet,CROP);//CROP這個常量是我之前已經定義好的。就是個動作代碼。
現在詳細說兩個地方,先說這一行代碼
intentGet.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(currentImageFile));
這一行其實也是寫給那個圖庫應用看的,圖庫選擇到一個圖片文件以後,圖庫會試圖把這個圖片複製到一個地方,也就是新建的那個文件,其實這行代碼可以這麼理解    圖庫輸出到哪(“輸出”,“打算輸出到的那個文件的位置”)。
好了,再上另外一行代碼的意思。
startActivityForResult(intent,動作代碼)
這個動作你要先去實現一個方法,就是onActivityResult(int requestCode, int resultCode, Intent data);
這個方法第一個參數是請求動作碼,第二個就是結果狀態碼,第三個就是返回的數據;
這個動作,先啓動你要執行的那個intent,然後會有執行結果返回(比如選擇一張圖片以後返回的值,返回的圖片數據什麼的)。
返回到哪呢?就是返回到相應的動作碼。這樣說起來有點模糊,看一下代碼吧。
重頭戲來了。
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode){
                //如果動作代碼是CROP,那麼當選圖完畢以後就執行這個裏面的代碼。
                case CROP:
                //準備打開系統的裁剪Activity
                Intent intentCrop = new Intent("com.android.camera.action.CROP"); 
               //這data裏面其實就是剛纔你選的那張照片的Uri。 
                intentCrop.setDataAndType(data.getData(),"image/*");
               //下面這個設置可以告訴裁剪程序:這個圖是否可以縮放
                intentCrop.putExtra("scale",true);
                //裁剪後保存到哪裏,這也是裁剪程序自己搞定的
                intentCrop.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(currentImageFile));
                startActivityForResult(intentCrop,UPLOAD);
                break;

            case UPLOAD:
               //這裏就寫UPLOAD代碼就行了。

        }


    }


這樣大概就結束了。
其實要掌握好邏輯就可以了。
startActivityForResult這個方法的流程一定要想明白,這個流程大概是這樣的:
(activityA,動作碼A)其實就是啓動activityA,將返回的結果傳到onActivityResult方法的相應動作碼A的代碼塊裏面。(然後你可以再啓動B,將B的結果返回到另外一個代碼塊裏面。)

如果有不懂的可以給我留言。











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章