成功將檔案由uri找到並貼在imageView上  

問題:

前陣子使用Android 裁剪照片的函式,由於Android對於裁剪com.android.camera.action.CROP

沒有寫得很清楚,後來研究了一下才發現有些圖片可以切,有些卻因為檔案過大無法返回,

網路上抄來抄去真的return-data幾乎都是true, 

Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType(“image/*”);
intent.putExtra(“crop”, “true”);

但是這用來切頭像 200x200以內的圖片是絕對可行的,因為檔案不大,

但用來切大照片,有可能因為超過傳回內存的容量16MB,絕對會有問題

原因是因為Android允許你使用return-data拿資料回來,再用(Bitmap)extras.getParcelable("data")拿到圖片

但這個方法檔案太大你就掰掰了,除非你限制user的檔案很小.

但通常你要裁剪多半都是照片

解決辦法:

不要讓Intent帶檔案回來給我們,改成我們自己創建檔案,使用uri方法去連結他

以下示範一個切成4比3的圖片

Uri uri2 = null ;

private void crop(Uri uri) {

                                // 裁剪圖片意圖

                                Intent intent = new Intent("com.android.camera.action.CROP");

                                intent.setDataAndType(uri, "image/*");

                                intent.putExtra("crop", "true");

                                // 裁剪框的比例,4:3

                                intent.putExtra("aspectX", 4);

                                intent.putExtra("aspectY", 3);

                                // 裁剪後輸出圖片的尺寸大小

                                //intent.putExtra("outputX", 1080);

                                //intent.putExtra("outputY", 810);  //像這個太大如果使用true,記憶體不夠就會出錯

                               

                                intent.putExtra("outputFormat", "JPEG");// 圖片格式

                                //intent.putExtra("noFaceDetection", true);// 取消人臉識別

                                intent.putExtra("return-data", false);

                                // 開啟一個帶有返回值的Activity,請求碼為PHOTO_REQUEST_CUT

                                String localTempImgDir="Hello";

                        String localTempImgFileName = System.currentTimeMillis()+".jpg";

                                File f=new File(Environment.getExternalStorageDirectory()

                                                +"/"+localTempImgDir+"/"+localTempImgFileName);

                                uri2 = Uri.fromFile(f); //用這個uri去做事

                    //intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);

                                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri2);

                                把他連結到uri2,如此返回時便可使用此uri2做事

                    //Toast.makeText( photoActivity.this, "targetUri ="+targetUri, Toast.LENGTH_SHORT ).show();

                    selectedImagePath = f.getAbsolutePath();

                    Log.w("TAG", "selectedImagePath:" + selectedImagePath);

                    View1.setText("selectedImagePath:"+selectedImagePath);

                   

                    mImageUri = Uri.fromFile(f);

                    strImage = f.getAbsolutePath();

                   

                    Log.w("TAG", "f.getAbsolutePath():"+ f.getAbsolutePath());

                                startActivityForResult(intent, PHOTO_REQUEST_CUT);

                        }

如此便解決了我大圖片一直無法返回,但圖片正確創立,也能正確顯示到圖片的問題!! 

成功測試各種 相簿選取/拍照 的裁剪都能正常使用 如下圖

尚未選圖片尚未選圖片時

 

 選取挑圖片的程式  選取挑圖片的程式

跳出裁剪照片  此處已挑好圖片以後,再跳出裁剪照片

選取裁剪範圍  選取裁剪範圍

成功將檔案由uri找到並貼在imageView上  成功將檔案由uri找到並set在imageView上

 

問題解決引用自:

http://www.linuxidc.com/Linux/2012-11/73939p2.htm

以下貼出部分他的CODE跟解說,確實很有幫助!

 

Crop String  發送裁剪信號

 

aspectX     int     X方向上的比例

 

aspectY     int     Y方向上的比例

 

outputX     int     裁剪區的寬

 

outputY     int     裁剪區的高

 

scale         Boolean     是否保留比例

 

return-data        Boolean     是否將資料保留在Bitmap中返回

 

data  Parcelable相應的Bitmap資料

 

MediaStore.EXTRA_OUTPUT ("output")URIURI指向相應的file:///...

這裡ex: intent.putExtra(MediaStore.EXTRA_OUTPUT, uri2);

 

方法1:如果你將return-data設置為“true”,你將會獲得一個與內部資料關聯的Action,並且bitmap以此方式返回:(Bitmap)extras.getParcelable("data")。注意:如果你最終要獲取的圖片非常大,那麼此方法會給你帶來麻煩,所以你要控制outputXoutputY保持在較小的尺寸。鑒於此原因,在我的代碼中沒有使用此方法((Bitmap)extras.getParcelable("data"))。

下麵是CropImage.java的源碼片段:

// Return the cropped image directly or save it to the specified URI.
Bundle myExtras = getIntent().getExtras();
if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data")))
{
    Bundle extras = new Bundle();
    extras.putParcelable("data", croppedImage);
    setResult(RESULT_OK,(new Intent()).setAction("inline-data").putExtras(extras));
    finish();
}

方法2如果你將return-data設置為“false”,那麼在onActivityResultIntent資料中你將不會接收到任何Bitmap,相反,你需要將MediaStore.EXTRA_OUTPUT關聯到一個Uri,此Uri是用來存放Bitmap的。

但是還有一些條件,首先你需要有一個短暫的與此Uri相關聯的檔位址,當然這不是個大問題(除非是那些沒有sdcard的設備)。

下麵是CropImage.java關於操作Uri的源碼片段:

if (mSaveUri != null) {
    OutputStream outputStream = null;
    try {
        outputStream = mContentResolver.openOutputStream(mSaveUri);
        if (outputStream != null) {
            croppedImage.compress(mOutputFormat, 75, outputStream);
        }
    } catch (IOException ex) {
        // TODO: report error to caller
        Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
    } finally {
        Util.closeSilently(outputStream);
    }
    Bundle extras = new Bundle();
    setResult(RESULT_OK, new Intent(mSaveUri.toString()).putExtras(extras));
}

 

文章標籤
創作者介紹

椿哥-分享之部落格

椿哥 發表在 痞客邦 PIXNET 留言(1) 人氣()


留言列表 (1)

發表留言
  • 俴 誏 ? 闚
  • 家於問孩會到大到在可做如重年,人要一要麼,定天中

    免費線上○看□ goo.gl/SbIKlX
找更多相關文章與討論