[Android] 拍照、截图、保存并显示在ImageView控件中
? ? 最近在做Android的項目,其中部分涉及到圖像處理的內容.這里先講述如何調用Camera應用程序進行拍照,并截圖和保存顯示在ImageView控件中以及遇到的困難和解決方法.
? ? PS:作者購買了本《Android第一行代碼 著:郭霖》,參照里面的內容完成(推薦該書,前面的布局及應用非常不錯).網上這類資料非常多,作者僅僅分享給初學者同時在線記錄些內容,希望對大家有所幫助.
? ?首先,設置activity_main.xml為LinearLayout布局且 android:orientation="vertical"
<Buttonandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="TakePhoto Button" /><ImageViewandroid:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content"android:layout_gravity="center_horizontal" />
? ?然后,在MainActivity.java文件中public class MainActivity extends Activity修改源代碼.添加自定義變量:
//自定義變量 public static final int TAKE_PHOTO = 1; public static final int CROP_PHOTO = 2; private Button takePhotoBn; private ImageView showImage; private Uri imageUri; //圖片路徑 private String filename; //圖片名稱 ? ?添加函數實現點擊拍照功能:
@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);takePhotoBn = (Button) findViewById(R.id.button1);showImage = (ImageView) findViewById(R.id.imageView1);//點擊"Photo Button"按鈕照相takePhotoBn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//圖片名稱 時間命名SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");Date date = new Date(System.currentTimeMillis());filename = format.format(date);//創建File對象用于存儲拍照的圖片 SD卡根目錄 //File outputImage = new File(Environment.getExternalStorageDirectory(),"test.jpg");//存儲至DCIM文件夾File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); File outputImage = new File(path,filename+".jpg");try {if(outputImage.exists()) {outputImage.delete();}outputImage.createNewFile();} catch(IOException e) {e.printStackTrace();}//將File對象轉換為Uri并啟動照相程序imageUri = Uri.fromFile(outputImage);Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); //指定圖片輸出地址startActivityForResult(intent,TAKE_PHOTO); //啟動照相//拍完照startActivityForResult() 結果返回onActivityResult()函數}});if (savedInstanceState == null) {getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();} } ? ?通過startActivityForResult和onActivityResult方法實現拍照截圖和保存功能:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode != RESULT_OK) { Toast.makeText(MainActivity.this, "ActivityResult resultCode error", Toast.LENGTH_SHORT).show();return; }switch(requestCode) {case TAKE_PHOTO:Intent intent = new Intent("com.android.camera.action.CROP"); //剪裁intent.setDataAndType(imageUri, "image/*");intent.putExtra("scale", true);//設置寬高比例intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);//設置裁剪圖片寬高intent.putExtra("outputX", 340);intent.putExtra("outputY", 340);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);Toast.makeText(MainActivity.this, "剪裁圖片", Toast.LENGTH_SHORT).show();//廣播刷新相冊 Intent intentBc = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);intentBc.setData(imageUri); this.sendBroadcast(intentBc); startActivityForResult(intent, CROP_PHOTO); //設置裁剪參數顯示圖片至ImageViewbreak;case CROP_PHOTO:try { //圖片解析成Bitmap對象Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));Toast.makeText(MainActivity.this, imageUri.toString(), Toast.LENGTH_SHORT).show();showImage.setImageBitmap(bitmap); //將剪裁后照片顯示出來} catch(FileNotFoundException e) {e.printStackTrace();}break;default:break;} }
? ? 由于涉及到SD卡中寫數據操作和Camera操作,需要在AndroidMainfest.xml文件中聲明權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> ? ??運行結果如下圖所示:
? ? ? ?
??? 需要注意以下幾個問題:
??? 1.拍照和截圖都涉及到startActivityForResult和onActivityResult的交互操作.
startActivityForResult(Intent intent, //Intent對象int requestCode //>=0 當Activity結束時requestCode將歸還在onActivityResult()中 ) onActivityResult(int requestCode, //提供給onActivityResult,以確認返回的數據是從哪個Activity返回的int resultCode, //由子Activity通過其setResult()方法返回 通常為RESULT_CANCELED或RESULT_OKIntent data //一個Intent對象,帶有返回的數據 )
? ?其中onActivityResult的requestCode和startActivityForResult中的requestCode相對應.同時結合Intent意圖實現拍照和截圖,核心代碼如下:(intent的參數設置省略)
? ??Intent intent = new?Intent("android.media.action.IMAGE_CAPTURE");
? ??startActivityForResult(intent,TAKE_PHOTO);
? ??Intent intent = new Intent("com.android.camera.action.CROP");?
? ??startActivityForResult(intent, CROP_PHOTO);
? ? 2.使用Android拍照保存在系統相冊,圖庫不能立刻顯示最新照片.解決方法是發送系統內置的廣播去刷新相冊實現顯示.代碼如下:
? ? 可能你會使用下面這條廣播掃描整個SD卡,但4.4已禁止這樣的操作:
sendBroadcast(new?Intent(Intent.ACTION_MEDIA_MOUNTED,?Uri.parse(...)))
? ? 參考資料?http://blog.csdn.net/xiaanming/article/details/8990627
? ? 3.當運行程序是可能會發現結果圖像顯示很小,當通過一個Intent意圖觸發時,Camera程序不會將全尺寸圖像返回給主調活動,這樣需要大量的內存,而移動設備內存會有一定限制.通常Camera將在返回的意圖中返回一幅很小的縮略圖,大圖可能會導致OOM問題.參考:《Android多媒體開發高級編程 著:Shawn Van Every》
??? 針對大圖像Android提供BitmapFactory類,允許通過各種資源加載Bitmap圖像.調用BitmapFactory.Options類可以定義如何將Bitmap讀入內存,當加載圖像時,可設置BitmapFactory采樣大小.并指定inSampleSize參數表明加載時結果Bitmap圖像所占的比例.如inSampleSize=8表明產生一副大小為原始圖像1/8的圖像.參考下面代碼:
??? 4.使用nexus 4 剪裁圖片后不能setImageBitmap顯示在ImageView控件中,其中只有保存按鈕,沒有剪裁按鈕.測試發現沒有返回RESULT_OK.這個問題不能解決.Why?
??? 參考:Unable to Save Photo Edits
??? 最后希望文章對大家有所幫助,這是我學習Android圖像處理部分的基礎性文章與解決過程.下載地址: http://download.csdn.net/detail/eastmount/8074833
參考資料和推薦博文:(都是非常不錯的資料-.-)
??? 《Android第一行代碼》著郭霖 參考8.3 調用攝像頭和相冊
??? android拍照圖片選取與圖片剪裁 By:Lee_Allen??
??? Android_照相機Camera_調用系統照相機返回data為空 By:strawberry2013
????Android圖片剪裁功能實心詳解 By:小馬
??? Android開發 拍照、圖片集保存照片技巧
??? Android 拍照并顯示在ImageView中(進階) By:leesa
??? android調動系統的照相機并把照片顯示在ImageView上
??? cameraintent data null in onActivityResult(int requestCode, int resultCode, Intentdata)
??? Android高效加載大圖、多圖解決方案,有效避免程序OOM By:guolin
??? Android相機、相冊獲取圖片顯示并保存到SD卡 By:唐韌_Ryan
??? android、獲取本地圖片|直接獲取照相圖片 By:zcljy0318
(By:Eastmount 2014-10-23 晚10點http://blog.csdn.net/eastmount/)
總結
以上是生活随笔為你收集整理的[Android] 拍照、截图、保存并显示在ImageView控件中的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Android] The connec
- 下一篇: [Android] 使用Matrix矩阵