上篇文章主要介紹了我開源在Github上的圖片剪裁庫(ImageCropper)的基本特性和用法,從本文開始,慢慢介紹一些開發圖片剪裁應用中涉及的知識點和技術。
其實Android系統本身也提供了圖片剪裁的模塊,我們可以直接通過Intent來調用系統的圖片剪裁功能,本文我們就先了解一下系統自帶的圖片剪裁功能是如何調用的吧。
得到被剪裁圖片的URL地址
既然是圖片剪裁,就一定要有被剪裁的圖片,由于圖片數據一般很大,為了防止內存溢出,普通APP與Android系統圖片剪裁應用之間是通過URL來傳遞圖片地址的。這個URL與我們常說見的網絡URL不一樣,它并不是HTTP開頭,而是以file或者content開頭的字符串,例如:
“file:///sdcard/test.jpg” “content://media/external/p_w_picpaths/media/21936”
這里,我們首先介紹獲取圖片URL的方法:
(1) 從SDCard中得到圖片的URL
假設知道圖片存放的路徑位于“/sdcard/test.jpg”,那么,可以通過下面這種方式來得到URL:
Uri p_w_picpathUri = Uri.fromFile(new File("/sdcard/test.jpg"));
當然,如果圖片是從網絡獲取的,并不存在于sdcard中,則可以先保存一份臨時文件到sdcard中,再通過上述方法得到URL。
注:通過這種方式得到的URL,一般以“file://”開頭。
(2) 從多媒體數據庫中得到圖片的URL
Android系統會在后臺定期掃描存儲在系統中的多媒體文件,如:音樂、圖片和視頻等,相關的信息會存放在系統的多媒體數據庫中,位于/data/data/com.android.providers.media/databases中,我們可以通過檢索該數據庫得到圖片的URL(例如:通過檢索數據庫得到系統最后一次添加/修改的照片URL),也可以通過Intent.ACTION_PICK來調用系統的圖片選擇器來選擇一張圖片,圖片選擇器會將圖片的URL地址放入Intent的data中返回。
后者的應用更多一些,我們主要介紹一下后者,即通過Intent.ACTION_PICK來得到圖片URL地址,方法如下:
public void pickImage() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("p_w_picpath/*"); startActivityForResult(intent,REQUEST_CODE_PICK_IMAGE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { return; } if( requestCode == REQUEST_CODE_PICK_IMAGE ) { Uri p_w_picpathUri = data.getData(); //...... } }
注:通過這種方式得到的URL,一般以“content://media”開頭。
(3) 調用系統的相機拍一張照片
當然,被剪裁的圖片也可以是通過Camera拍攝的一張照片,方法如下:
Uri pictureURL = Uri.fromFile(new File("/sdcard/temp.jpg")); public void takenPicture() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureURL ); startActivityForResult(intent,REQUEST_CODE_TAKEN_PICTURE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { return; } if( requestCode == REQUEST_CODE_TAKEN_PICTURE ) { Uri p_w_picpathUri = pictureURL; //...... } }
通過代碼你可能已經注意到了,其實這種方式得到的圖片URL,與第一種方式是一樣的,通過圖片的存儲路徑轉化過來的,只不過傳遞給了系統Camera應用中。
2. 通過Intent調用系統的圖片剪裁功能
有了圖片的URL,調用系統的圖片剪裁就很簡單了,只需要構建一個Intent對象,并設置相關參數即可,用法示例如下:
public void test( Uri p_w_picpathUri ) { Uri croppedUri = Uri.fromFile(new File("/sdcard/cropped.jpg")); startSystemCropImage(p_w_picpathUri,croppedUri); } public void startSystemCropImage( Uri src, Uri dst ) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.putExtra("crop", "true"); // 設置剪裁圖片的源/目的地址URL intent.setDataAndType(src,"p_w_picpath/*"); intent.putExtra(MediaStore.EXTRA_OUTPUT,dst); // 設置剪裁圖片的寬高比 //intent.putExtra("aspectX", 2); //intent.putExtra("aspectY", 1); // 固定剪裁圖片的寬高值 //intent.putExtra("outputX", 680); //intent.putExtra("outputY", 480); // 為了防止內存限制以及各個廠商返回的數據不統一,建議不要直接使用這個返回的數據,而是數據返回的URL intent.putExtra("return-data", false); startActivityForResult(intent, REQUEST_CODE_SYSTEM_CROPPER); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { return; } if( requestCode == REQUEST_CODE_IMAGE_CROPPER ) { Uri croppedUri = data.getExtras().getParcelable(MediaStore.EXTRA_OUTPUT); InputStream in = null; try { in = getContentResolver().openInputStream(croppedUri); Bitmap b = BitmapFactory.decodeStream(in); mImageView.setImageBitmap(b); } catch (FileNotFoundException e) { e.printStackTrace(); } } super.onActivityResult(requestCode, resultCode, data); }
3. 小結
注意添加讀寫SDCard的權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
關于調用系統的圖片剪裁應用就介紹到這兒了,有任何疑問歡迎留言或者來信lujun.hust@gmail.com交流,或者關注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。