首页 文章

Android相机意图:如何获得全尺寸照片?

提问于
浏览
50

我正在使用意图启动相机:

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);

但它只是一个缩略图,我如何获得完整的位图?我知道我可以使用自己的Activity并使用:

Camera.PictureCallback()

但无论如何使用Intent做到了吗?

谢谢!

编辑:

我也尝试过:

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

它适用于从库中选择的照片,但对于相机意图,data.getData()返回null .

6 回答

  • 31

    要获得全尺寸的相机图像,您应该将相机保存到临时文件中,例如:

    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)
    {
        //MenuShootImage is user defined menu option to shoot image
        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);
    }
    

    P.S. 代码需要针对Android M中应用的新安全限制进行修订 - FileProvidermImageUri 必须打包 FileProvider

  • 0

    Open Camera and save image into some specific directory

    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);
    
            }
        }
    
    }
    
  • 100

    尽管这是一个古老的问题而且它有一个公认的答案,
    我想分享我的解决方案 .
    在这种情况下,您不必创建临时文件 .
    另外我们 creating a chooser which offers to user both: take a picture with the camera or pick an existing one from a gallery.

    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);
        }
    }
    
  • 6

    我也使用了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);
    }
    

    在创建期间从保存的包中检索它:

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

    要从相机捕获最大图片大小,我希望这些简单的步骤将非常有用

    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);
    

    这里,获取每个移动设备所支持的大小,从大小最大的那个被固定为要捕获的图片大小 .

  • 1

    不要在AndroidManifest中使用 onActivityResult 's data. It took me many hours to test different solutions. A camera saves a picture (even if you don' t设置权限进行相机和读卡,但是 onActivityResult 会返回 data == null 并且 MediaStore 会返回错误的路径 . 在这些解决方案中,您只需获取上一个图库图片,而不是您的照

    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);
    }
    

相关问题