這種保存圖片的好處:在有限的內存下,管理許多全尺寸的圖片會很棘手。如果發現應用在展示了少量圖片後消耗了所有內存,我們可以通過縮放圖片到目標視圖尺寸,之後再載入到內存中的方法,來顯著降低內存的使用。
demo已解決的問題:在onCreate()得到控件的寬度和長度,
在onCreate()方法中調用
ViewTreeObserver vto = image.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { targetH = image.getMeasuredHeight(); targetW = image.getMeasuredWidth(); return true; } });
如果希望照片對我們的應用而言是私有的,那麼可以使用getExternalFilesDir()提供的目錄
如果希望照片對所有應用共享,那麼可以使用getExternalStoragePublicDirectory()提供的目錄
首先加一個寫的權限
<manifest
...>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
按鈕點擊
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //判斷是否有相機 if (intent.resolveActivity(getPackageManager()) != null) { File photoFIle=null; try { photoFIle = createImageFile(); } catch (Exception e) { e.printStackTrace(); } if (photoFIle != null) { //怎麼將拍好的照片保存在sd卡中? /* 首先在sd卡中創建一個空的.jpg文件,然後獲取創建好的.jpg的uri, 接着通過intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFIle)); MediaStore.EXTRA_OUTPUT這個表示照相完成後保存圖片在uri這個.jpg文件中 */ intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFIle)); gallerAddPic(); startActivityForResult(intent,REQUEST_IMAGES); } } } });
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGES && resultCode == RESULT_OK) { setPic(); /* Bundle bundle=data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); image.setImageBitmap(bitmap);*/ } }
private void setPic(){ Log.d("test", targetH+";;;"); BitmapFactory.Options bmOptions=new BitmapFactory.Options(); bmOptions.inJustDecodeBounds=true;//設置inJustDecodeBounds爲true後,decodeFile並不分配空間,但可計算出原始圖片的長度和寬度 //bmOptions指向mCurrentPhotoPaht路徑中的圖片 BitmapFactory.decodeFile(mCurrentPhotoPaht, bmOptions); //之所以phtotW=0是因爲mCurrentPhotoPaht的路徑出錯,找不到拍照後保存下的圖片 float photoW=bmOptions.outHeight; float photoH=bmOptions.outHeight; Log.d("test", "photoW" + photoW); float scaleFactor = Math.min(photoW / targetW, photoH / targetH);//設置縮放比例 bmOptions.inJustDecodeBounds=false;// bmOptions.inSampleSize=(int) scaleFactor; bmOptions.inPurgeable=true;//inPurgeable:設置爲True時,表示系統內存不足時可以被回 收 Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPaht, bmOptions); image.setImageBitmap(bitmap); } //觸發系統的Media Scanner,將我們的照片添加到Media Provider的數據庫中,就是將照片添加到相冊,拍照後你就可以在相冊中看到 private void gallerAddPic(){ Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); Log.d("test", mCurrentPhotoPaht + ":gallerAddPic"); File f = new File(mCurrentPhotoPaht); Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } private File createImageFile() throws IOException{ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File image = File.createTempFile(imageFileName, ".jpg", storageDir); mCurrentPhotoPaht=image.getAbsolutePath(); Log.d("test", mCurrentPhotoPaht); return image; }
//保存路徑長度,寬度,防止重建Activity時長度,寬度,mCureentPhotoPaht出錯
@Override protected void onSaveInstanceState(Bundle outState) { outState.putString("path",mCurrentPhotoPaht); outState.putInt("w",targetW); outState.putInt("h",targetH); Log.d("test", "onSaveInstance"+mCurrentPhotoPaht); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { mCurrentPhotoPaht = savedInstanceState.getString("path"); targetH = savedInstanceState.getInt("h"); targetW = savedInstanceState.getInt("w"); Log.d("test", "onresotre:" + mCurrentPhotoPaht); super.onRestoreInstanceState(savedInstanceState); }