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

hzx*_*zxu 57 camera android bitmap

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

Intent cameraIntent = new Intent(
    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getParent().startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
Run Code Online (Sandbox Code Playgroud)

和使用:

Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
photoImage.setImageBitmap(thumbnail);
photoImage.setVisibility(View.VISIBLE);
Run Code Online (Sandbox Code Playgroud)

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

Camera.PictureCallback()
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

编辑:

我也尝试过:

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

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

Bar*_*ica 104

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

    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);
}
Run Code Online (Sandbox Code Playgroud)

然后在图像捕获意图完成后 - 只需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);
}
Run Code Online (Sandbox Code Playgroud)

PS Code需要针对Android M中应用的新安全限制进行修改 - FileProvider:mImageUri必须打包FileProvider

  • 只是想指出上面重要的一行是`intent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri);`请参阅http://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE以获取难以捉摸的文档关于这种行为. (5认同)
  • 我尝试过这个解决方案,但是图像的结果是这样的错误:java.lang.RuntimeException:将结果ResultInfo {who = null,request = 188,result = -1,data = null}传递给activity {失败.ketanolab.lbc/com.ketanolab.lbc.Robototal}:java.lang.NullPointerException (5认同)

Vic*_*cky 37

打开相机并将图像保存到某个特定目录中

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);
}
Run Code Online (Sandbox Code Playgroud)

处理图像

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

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 也是唯一正在工作的......我真的不明白为什么这么简单的任务应该这么复杂 (6认同)
  • 在互联网上搜索24小时后,这是唯一能完成我想要的代码.现在唯一的问题是,即使我在人像模式下拍摄,也会以横向模式显示图像. (5认同)
  • 请记住,您需要 WRITE_EXTERNAL_STORAGE 权限。此答案中的代码来自 https://developer.android.com/training/camera/photobasics.html (2认同)

Leo*_*der 6

即使这是一个老问题而且它有一个公认的答案,
我想分享我的解决方案.
在这种情况下,您不必创建临时文件.
此外,我们还创建了一个选择器,为用户提供:使用相机拍照或从图库中选择现有照片.

    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);
Run Code Online (Sandbox Code Playgroud)

在这里我们检索结果:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个和许多其他答案返回相机的最后一个画廊图像而不是相机镜头。在 API 23 模拟器和 API 21 设备中测试。Uri 引用与原始照片不同的路径。还有数据 == 空。 (3认同)