2011-06-23 181 views
44

我使用意圖啓動相機:Android相機意圖:如何獲得全尺寸的照片?

Intent cameraIntent = new Intent(
    android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
getParent().startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST); 

和使用:

Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); 
photoImage.setImageBitmap(thumbnail); 
photoImage.setVisibility(View.VISIBLE); 

但它僅僅是一個縮略圖,如何獲取完整的位圖?我知道我可以用我自己的活動,並使用:

Camera.PictureCallback() 

但反正是有做使用意圖呢?

謝謝!

編輯:

我也試過:

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    Uri uri = data.getData(); 
    imageView.setImageURI(uri); 
} 

它適用於從圖庫中選擇照片,但對相機的意圖,data.getData()返回null。

回答

94

要獲得全尺寸的攝像機圖像,你應該指向相機保存照片的臨時文件,如:

private URI mImageUri; 

    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
    File photo; 
    try 
    { 
     // place where to store camera taken picture 
     photo = this.createTemporaryFile("picture", ".jpg"); 
     photo.delete(); 
    } 
    catch(Exception e) 
    { 
     Log.v(TAG, "Can't create file to take picture!"); 
     Toast.makeText(activity, "Please check SD card! Image shot is impossible!", 10000); 
     return false; 
    } 
    mImageUri = Uri.fromFile(photo); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); 
    //start camera intent 
    activity.startActivityForResult(this, intent, MenuShootImage); 

private File createTemporaryFile(String part, String ext) throws Exception 
{ 
    File tempDir= Environment.getExternalStorageDirectory(); 
    tempDir=new File(tempDir.getAbsolutePath()+"/.temp/"); 
    if(!tempDir.exists()) 
    { 
     tempDir.mkdirs(); 
    } 
    return File.createTempFile(part, ext, tempDir); 
} 

再經過圖像拍攝意圖完成工作 - 使用下面的代碼從imageUri只要抓住你的照片:

public void grabImage(ImageView imageView) 
{ 
    this.getContentResolver().notifyChange(mImageUri, null); 
    ContentResolver cr = this.getContentResolver(); 
    Bitmap bitmap; 
    try 
    { 
     bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri); 
     imageView.setImageBitmap(bitmap); 
    } 
    catch (Exception e) 
    { 
     Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "Failed to load", e); 
    } 
} 


//called after camera intent finished 
@Override 
public void onActivityResult(int requestCode, int resultCode, Intent intent) 
{ 
    if(requestCode==MenuShootImage && resultCode==RESULT_OK) 
    { 
     ImageView imageView; 
     //... some code to inflate/create/find appropriate ImageView to place grabbed image 
     this.grabImage(imageView); 
    } 
    super.onActivityResult(requestCode, resultCode, intent); 
} 
+0

感謝我現在就試試吧。 – hzxu

+0

我試了一下,URI是文件:///sdcard/.temp/picture19010.jpg,我用的ImageView setImageUri(),但它不工作,是路徑正確,或者我需要的東西,使URI識別通過imageview? – hzxu

+0

@hzxu:我加入了圖像採集碼 - 看上面 – barmaley

27

打開攝像機並保存圖像到一些特定的目錄

private String pictureImagePath = ""; 
private void openBackCamera() { 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String imageFileName = timeStamp + ".jpg"; 
    File storageDir = Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES); 
    pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName; 
    File file = new File(pictureImagePath); 
    Uri outputFileUri = Uri.fromFile(file); 
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);    
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
    startActivityForResult(cameraIntent, 1); 
} 

地處理圖像

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == 1) { 
    File imgFile = new File(pictureImagePath); 
     if(imgFile.exists()){   
     Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); 
     ImageView myImage = (ImageView) findViewById(R.id.imageviewTest); 
     myImage.setImageBitmap(myBitmap); 

     } 
    } 

} 
+4

搜索了24小時的互聯網後,這是唯一的代碼做了我想要的。現在唯一的問題是,即使在縱向模式下,它也會以橫向模式顯示圖像。 –

+3

也是唯一一個工作.....我真的不明白爲什麼這麼簡單的任務應該如此複雜 –

+1

記住你需要WRITE_EXTERNAL_STORAGE權限。這個答案的代碼是從https://developer.android.com/training/camera/photobasics.html – patraulea

4

儘管這是一個老問題,它有一個公認的答案,
我想與大家分享我的解決方案。
在這種情況下,您不必創建臨時文件。
此外,我們創建一個選擇器,向用戶提供:使用相機拍攝照片或從畫廊中選擇現有的選擇器。

Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    Intent chooser = new Intent(Intent.ACTION_CHOOSER); 
    chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent); 
    chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.chooseaction)); 
    Intent[] intentArray = {cameraIntent}; 
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); 
    startActivityForResult(chooser, RESULT_LOAD_IMAGE); 

在這裏,我們檢索結果:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // todo use appropriate resultCode in your case 
    if (requestCode == RESULT_LOAD_IMAGE && resultCode == FragmentActivity.RESULT_OK) { 
     if (data.getData() != null) { 
      // this case will occur in case of picking image from the Gallery, 
      // but not when taking picture with a camera 
      try { 
       Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData()); 

       // do whatever you want with the Bitmap ....   

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } else { 
      // this case will occur when taking a picture with a camera 
      Bitmap bitmap = null; 
      Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
        new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED, 
          MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED, 
        null, "date_added DESC"); 
      if (cursor != null && cursor.moveToFirst()) { 
       Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))); 
       String photoPath = uri.toString(); 
       cursor.close(); 
       if (photoPath != null) { 
        bitmap = BitmapFactory.decodeFile(photoPath); 
       } 
      } 

      if (bitmap == null) { 
       // for safety reasons you can 
       // use thumbnail if not retrieved full sized image 
       bitmap = (Bitmap) data.getExtras().get("data"); 
      } 
      // do whatever you want with the Bitmap .... 
     } 

     super.onActivityResult(requestCode, resultCode, data); 
    } 
} 
+0

真的很不錯,因爲它不需要readExternalStorage權限。本地相機或圖庫選擇器也是用戶完成動作的舒適方式 – Ragaisis

+0

這個以及許多其他答案會返回相機的最後一個圖庫圖像,而不是相機鏡頭。經過API 23仿真器和API 21設備的測試。 Uri引用與原始照片不同的路徑。另外數據== null。 – CoolMind

+0

嘗試這一點:如果我選擇畫廊,一切工作如這裏所述。但是如果我選擇cameraCode == REQUEST_CANCELLED。 – jwehrle

0

我還用從玉萍的答案,但我不得不到URI保存到一個包,以避免方向的改變它的損失。所以如果你在傾斜設備後沒有從你的意圖中得到結果,那可能是因爲你的uri沒有在方向改變中倖存下來。

static final int CAMERA_CAPTURE_REQUEST = 1; 
static final String ARG_CURRENT_PIC_URI = "CURRENT_PIC_URI"; 


String pictureImagePath = folderName + "/" + imageFileName; 
File file = new File(Environment.getExternalStorageDirectory(), pictureImagePath); 
Uri outputFileUri = Uri.fromFile(file); 

mCurrentPicUri = outputFileUri.getPath(); 

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); 
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST); 

活動結果代碼:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (requestCode == CAMERA_CAPTURE_REQUEST && resultCode == Activity.RESULT_OK) 
    { 
    File imgFile = new File(mCurrentPicUri); 
    // do something with your image 
    // delete uri 
    mCurrentPicUri = ""; 
    } 
} 

的URI保存到包:在上

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    // save uri to bundle 
    outState.putString(ARG_CURRENT_PIC_URI, mCurrentPicUri); 
} 

從保存的包找回它創建:

if (bundle.containsKey(ARG_CURRENT_PIC_URI)) 
    mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI); 
0

要從ca中捕獲最大圖片大小照相機,希望這些簡單的步驟將是非常有用的

public static Camera mCamera; 

Camera.Parameters parameters = mCamera.getParameters(); 
    parameters.getSupportedPictureSizes(); 
List<Camera.Size> supportedSizes = parameters.getSupportedPictureSizes(); 
    mSizePicture1 = supportedSizes.get(0); 
    int cameraSize = supportedSizes.size(); 
    mSizePicture2 = supportedSizes.get(cameraSize - 1); 

    if (mSizePicture1.height < mSizePicture2.height) 
     mSizePicture = supportedSizes.get(cameraSize - 1); 
    else 
     mSizePicture = supportedSizes.get(0); 

parameters.setPictureSize(mSizePicture.width, mSizePicture.height); 

在這裏,每個移動的被支持的規模被取,從該尺寸是最大的是被固定爲圖像尺寸來捕獲。

0

不要使用onActivityResult的數據。我花了很多時間來測試不同的解決方案。相機保存的照片(即使您沒有設置攝像頭和卡讀取AndroidManifest權限),但隨後onActivityResult回報data == nullMediaStore回報錯誤的道路。在這些解決方案中,您只需獲取最後一個圖庫圖像,而不是照片

private Uri photoUri; 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 

    ... 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    if (requestCode == CAMERA_RESULT) { 
     if (resultCode == RESULT_OK) { 
      if (photoUri != null) { 
       image.setImageURI(photoUri); 
      } 
     } 
    } 
} 

private void showCamera() { 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (intent.resolveActivity(getContext().getPackageManager()) != null) { 
     File file = null; 
     try { 
      file = createImageFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     photoUri = null; 
     if (file != null) { 
      photoUri = Uri.fromFile(file); 
      intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); 
      startActivityForResult(intent, CAMERA_REQUEST); 
     } 
    } 
} 

private File createImageFile() throws IOException { 
    // Create an image file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
    // File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
    return File.createTempFile(timeStamp, ".jpg", storageDir); 
} 
相關問題