web-dev-qa-db-ja.com

android:「保存」/「削除」の確認なしでカメラの写真を撮る

カメラから撮影した画像をImageViewに表示したい

Intent intent = new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

これは今のところ問題なく動作しますが、ユーザーが選択したカメラアプリを使用して写真を撮った後、(少なくともアプリから)撮影した写真を保存するか削除するかを尋ねるダイアログが表示されます(少なくともAndroid 2.3および4.2デフォルトのカメラアプリを使用)。

この追加のダイアログをスキップそしてImageViewに画像を直接表示したい(onActivityResultが呼び出されたとき)これはユーザーにとって追加の対話ステップを意味するため、ユーザーには可能性があるため不要ですアプリで写真を保存または削除します。

これは単純なACTION_IMAGE_CAPTUREインテントを使用して可能ですか、それともこの目的のためにCamera PreviewやSurfaceViewなどのより複雑なものが必要ですか?

16
fritz

SurfaceViewを使用して画像をキャプチャできます

_package com.camera;

import Java.io.IOException;

import Android.app.Activity;
import Android.content.Intent;
import Android.hardware.Camera;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.SurfaceHolder;
import Android.view.SurfaceView;
import Android.view.View;
import Android.widget.Button;
import Android.widget.Toast;

public class Camera_capture extends Activity implements SurfaceHolder.Callback {

private Camera mCamera;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Button capture_image;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_layout);
    capture_image = (Button) findViewById(R.id.capture_image);
    capture_image.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            capture();
        }
    });
    surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(Camera_capture.this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);
    try {
        mCamera = Camera.open();
        mCamera.setPreviewDisplay(surfaceHolder);
        mCamera.startPreview();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void capture() {
    mCamera.takePicture(null, null, null, new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Toast.makeText(getApplicationContext(), "Picture Taken",
                    Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.putExtra("image_arr", data);
            setResult(RESULT_OK, intent);
            camera.stopPreview();
            if (camera != null) {
                camera.release();
                mCamera = null;
            }
            finish();
        }
    });
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    Log.e("Surface Changed", "format   ==   " + format + ",   width  ===  "
            + width + ", height   ===    " + height);
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.e("Surface Created", "");
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    Log.e("Surface Destroyed", "");
}

@Override
protected void onPause() {
    super.onPause();
    if (mCamera != null) {
        mCamera.stopPreview();
        mCamera.release();
    }
}
}
_

そして、レイアウトファイルは

_<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >

<SurfaceView
    Android:id="@+id/surfaceview"
    Android:layout_width="fill_parent"
    Android:layout_weight="100"
    Android:layout_height="wrap_content" />

<Button
    Android:id="@+id/capture_image"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:layout_weight="1"
    Android:text="Capture" />

</LinearLayout>
_

この_Camera_capture_アクティビティをstartActivityForResultonActivityResultで開始すると、画像をbyte配列として取得できます。

_byte[] image = data.getExtras().getByteArray("image_arr");
_

ここで、dataは受信データです。

を使用してbyte配列をBitmapにデコードします

_Bitmap bmp = BitmapFactory.decodeByteArray(image, 0,
                    image.length);
_

これをBitmapに設定します


編集

_byte[]_を返す際に問題が発生するため、_byte[]_をファイルに保存し、ファイルを読み取ることができるように、ファイルのパスを前のActivityに送信する必要があります。

onPictureTaken()に、追加するだけです

_String PATH = "Any path to store a file";
try {
    FileOutputStream fos=new FileOutputStream(PATH);

    fos.write(data);
    fos.close();
  }
  catch (Java.io.IOException e) {

  }
_

の代わりに:

_intent.putExtra("image_arr", data);
_

書く

_intent.putExtra("image_path", PATH);
_

前のActivityonActivityResultでこのパスを次のように受け取ります:

_String imagePath = data.getExtras().getString("image_path");
_
16
AnujMathur_07

「Android.intent.extra.quickCapture」を使用する

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("Android.intent.extra.quickCapture",true);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}

画像が回転している場合は、次を使用できます。

mCamera.setDisplayOrientation(90);

mCamera.startPreview();
2
Energy Dome

デフォルトのインテントを使用してそれを行うことはできません。 Ok]ボタンと[キャンセル]ボタンを使用してプレビューをスキップできるカスタマーカメラキャプチャ機能を作成する必要があります。

どうぞ http://developer.Android.com/guide/topics/media/camera.html#custom-camera

1
Tahir Mehmood

AnujMathur_07のソリューションを使用できますが、パスとファイルを操作したくない場合は、メソッドonPictureTakenで、ビットマップを返すことができます。

 @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Toast.makeText(getApplicationContext(), "Picture Taken",
                        Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();

            Bitmap bmp = BitmapFactory.decodeByteArray(data, 0,
                    data.length);

            intent.putExtra("image", bmp);
            setResult(RESULT_OK, intent);
            camera.stopPreview();
            if (camera != null) {
                camera.release();
                mCamera = null;
            }
            finish();
        }

そして、メソッドonActivityResultで、ビットマップを取得できます。

 Bundle extras = data.getExtras();
 Bitmap imageBitmap = (Bitmap) extras.get("image");
1
alexcornejo