標籤:android style blog http io color ar for sp
我們很多時候需要進行圖片的裁剪,其實這個功能在android系統中已經有一套解決方案了,雖然介面和效果並不是很優秀但功能毫無疑問是完美實現了。至於,不用內建的方案怎麼做自訂,這個就是後話了。本篇主要講解的是裁剪的原理和流程,外帶分析了大圖裁剪和小圖裁剪的不同之處,同時給出具體的實現方案。
一、原理+流程
andorid提供了一個action,com.android.camera.action.CROP,
是Intent intent = new Intent("com.android.camera.action.CROP");
通過這個action就可以實現圖片的裁剪,具體就是實現這個intent,然後在這個intent中putExtra()中put各種參數,最後通過來啟動一個startActivityForResult(intent, requestCode);,這是裁剪圖片的activity,進行裁剪。
裁剪完後返回一個bitmap,交給開發人員進行處理。
也就是說,我們是通過系統寫好的Activity進行了主要的操作,自己只需要在activity類中的onActivityResult中根據requestCode來進行判斷和處理即可。
啟動系統相簿的Activity:
啟動系統照相的Activity:
啟動裁剪圖片的Activity:
二、主要問題
如果我們截取的圖片是大圖,那麼我們首先會想著提高輸出圖片的大小
// outputX outputY 是裁剪圖片寬高intent.putExtra("outputX", 800);intent.putExtra("outputY", 800);
但這樣就會出現問題,由於圖片過大,佔用記憶體過多所以系統會自行將圖片進行壓縮,以避免出現OOM的問題。下面摘錄一篇博文的部分內容來解釋這個問題:
原文:http://blog.csdn.net/floodingfire/article/details/8144604
在Android中,Intent觸發Camera程式,拍好照片後,將會返回資料,但是考慮到記憶體問題,Camera不會將全尺寸的映像返回給調用的Activity,一般情況下,有可能返回的是縮圖,比如120*160px。
這是為什麼呢?這不是一個Bug,而是經過精心設計的,卻對開發人員不透明。以我的小米手機為例,網路攝影機800W像素,根據我目前設定拍出來的圖片尺寸為3200*2400px。有人說,那就返回唄,大不了耗1-2M的記憶體,不錯,這個尺寸的圖片確實只有1.8M左右的大小。但是你想不到的是,這個尺寸對應的Bitmap會耗光你應用程式的所有記憶體。Android出於安全性考慮,只會給你一個寒磣的縮圖。
在Android2.3中,預設的Bitmap為32位,類型是ARGB_8888,也就意味著一個像素點佔用4個位元組的記憶體。我們來做一個簡單的計算題:3200*2400*4 bytes = 30M。
如此驚人的數字!哪怕你願意為一張生命週期超不過10s的位元影像願意耗費這麼巨大的記憶體,Android也不會答應的。
1 |
Mobile devices typically have constrained system resources. |
2 |
Android devices can have as little as 16MB of memory available to a single application. |
這是Android Doc的原文,雖然不同手機系統的廠商可能圍繞16M這個數字有微微的上調,但是這30M,一般的手機還真揮霍不起。也只有小米這種牛機,記憶體堪比個人PC,本著土財主般揮金如土的霸氣才能做到。
得出的結論是,如果你截取的是小圖那麼就返回一個bitmap,但如果是大圖那麼就返回一個uri。這樣就不會出現問題啦。
三、從相簿中
參考自:http://blog.csdn.net/floodingfire/article/details/8144615
現在原作者託管的代碼已經用了lib包作為例子了,和部落格中略有差異。
原作者博文中寫了兩種方式,我個人用的不是很習慣。自己覺得如果裁剪的大圖小圖我們懶得判斷,那麼直接統一返回uri就解決了所有問題啦,所以自己用下面的寫法。
詳細解釋如何通過Android內建的方式來實現圖片的裁剪——原理分析+解決方案