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); }
它适用于从图库中select的照片,但对于照相机意图,data.getData()返回null。
要获得全尺寸的相机图像,您应该指向相机以将图片保存在临时文件中,如:
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); }
打开相机并将图像保存到某个特定的目录
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); } } }
尽pipe这是一个古老的问题,并且有一个可以接受的答案,
我想分享我的解决scheme。
在这种情况下,您不必创build临时文件。
另外,我们创build一个select器,向用户提供:使用相机拍摄照片或从画廊中选取现有的照片。
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); } }
我也使用了Vicky的答案,但我必须将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); }
在创build时从保存的包中检索它:
if (bundle.containsKey(ARG_CURRENT_PIC_URI)) mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI);
为了从相机捕捉最大的图片大小,我希望这些简单的步骤将是非常有用的
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);
在这里,每个移动设备所支持的尺寸是从被固定为图片尺寸的最大尺寸捕获的。