如何使用原生Android相机捕获图像并存储

35

我遇到了一个问题,无法从本地相机应用程序中捕获并存储图像。以下是我的一些代码示例:

_path = Environment.getExternalStorageDirectory() + "make_machine_example.jpg";
File file = new File( _path );
Uri outputFileUri = Uri.fromFile( file );

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );

startActivityForResult( intent, 0 );

拍照后我回到原来的Activity,当我通过Android DDMS文件浏览器导航到SD卡时,照片并不在那里。有人知道为什么没有保存吗?


大家好,我想通过Android的本机相机捕获图像并储存它...所以我提供了悬赏,因为这件事让我感到困扰。 - Paresh Mayani
Paresh,你在捕获图像方面遇到了什么问题?这个问题中展示的方法对你不起作用吗? - Janusz
@Janusz 我需要放置一个TextView(活动名称),一个按钮(在底部),并且在屏幕中央有相机预览。在按钮点击事件上,应该拍摄照片并将照片显示在另一个活动的ImageView中。 - Paresh Mayani
那么您不想使用原生的Android相机应用程序。这个问题提供了一个示例,说明如何在您自己的应用程序中获取图像而不显示相机预览等内容。 - Janusz
@Janusz那我该怎么办?如果我为此提出一个问题...那么公众会提出“重复”的问题...而在我的应用程序中,需要显示“相机预览”以拍照...感谢您的支持。 - Paresh Mayani
显示剩余3条评论
5个回答

29

以下是最终产品,以防仍有人查看此线程:

public class CameraCapture extends Activity {

    protected boolean _taken = true;
    File sdImageMainDirectory;

    protected static final String PHOTO_TAKEN = "photo_taken";

    @Override
    public void onCreate(Bundle savedInstanceState) {

        try {

            super.onCreate(savedInstanceState);         
                    File root = new File(Environment
                            .getExternalStorageDirectory()
                            + File.separator + "myDir" + File.separator);
                    root.mkdirs();
                    sdImageMainDirectory = new File(root, "myPicName");


                startCameraActivity();
            }
        } catch (Exception e) {
            finish();
            Toast.makeText(this, "Error occured. Please try again later.",
                    Toast.LENGTH_SHORT).show();
        }

    }

    protected void startCameraActivity() {

        Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);

        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

        startActivityForResult(intent, 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (resultCode) {
        case 0:
            finish();
            break;

        case -1:

            try {
                StoreImage(this, Uri.parse(data.toURI()),
                        sdImageMainDirectory);
            } catch (Exception e) {
                e.printStackTrace();
            }

            finish();
            startActivity(new Intent(CameraCapture.this, Home.class));

        }

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
            _taken = true;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
    }

        public static void StoreImage(Context mContext, Uri imageLoc, File imageDir) {
        Bitmap bm = null;
        try {
            bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
            FileOutputStream out = new FileOutputStream(imageDir);
            bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
            bm.recycle();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

1
你需要在清单文件中设置额外的权限吗?我无法将我的名字赋予保存到SD卡的图像文件。 - Vincent
代码有点过期了,但第一个 try/catch 块中有一个额外的闭合括号。我将把它提取到 gist 中,除非你有任何反对意见。@ninjasense - ocodo
我正在使用相同的代码,但我想在处理图像之前向用户显示预览。有人知道如何在图像处理之前向用户显示预览吗? - Android is everything for me
1
在我的情况下,onActivityResult 没有被调用。它将图像保存在目录中,但不会进入下一个活动,该活动写在 onActivityResult 方法中。 - rupesh
@ninjasense 请在这个问题上帮我。 - rupesh
显示剩余2条评论

21

您是否检查了Environment.getExternalStorageDirectory()的输出,因为如果它不包含尾部文件分隔符(/),那么您的图像将最终保存在不位于SD卡上的目录中,例如:

 /mnt/sdcardmake_machine_example.jpg

当你真正想要的是:

 /mnt/sdcard/make_machine_example.jpg

试试这段代码:

 _path = Environment.getExternalStorageDirectory() + File.separator +  "make_machine_example.jpg";

2
是的,我可以确认您需要添加文件分隔符。 - Mathias Conradt

14

1 . 只需使用以下代码:

new File(Environment.getExternalStorageDirectory(),  "make_machine_example.jpg");

不必担心分隔符。

2. 之前也遇到过同样的问题。SenseUI手机有一个自定义相机应用程序,不会创建文件。您使用的是什么设备?最新设备可能已经修复了这个问题,但它也可能仍然存在。因此,这里提供了一个完整的示例,说明如何解决这个问题Problems saving a photo to a file


1

在保存图像后,您应该执行媒体扫描。

 sendBroadcast(new Intent(
            Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + Environment.getExternalStorageDirectory())));

-7
将以下代码添加到AndroidManifest.xml文件中,并删除make_machine_example扩展: 这将开始捕获照片并将其存储到SD卡中。

1
它不会存储捕获的图像。 - W I Z A R D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接