@blog.justoneplanet.info

日々勉強

androidでカメラを使う

凄く基本的なコード。別にすごいことはしてない。備忘録程度。

■カメラを起動する

AndroidManifest.xml

以下の記述をManifestファイルに記述してカメラを使えるようにする。

<uses-permission android:name="android.permission.CAMERA" />

以下の記述をactivityの属性に追記し、カメラの向きを端末の向きに合わせる。

<activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="landscape">

MainActivity.java

まぁ、いつも通りベタに書いておく。ちょっと違うのはCameraPreviewクラスをインスタンス化して使用する部分。

package jp.info.justoneplanet.android.usecamera;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);// titleの表示分で縦横比が崩れる
        mCameraPreview = new CameraPreview(this);
        setContentView(mCameraPreview);
    }
}

CameraPreview.java

SurfaceViewを継承してカメラを実際に扱う部分を作る。

package jp.info.justoneplanet.android.usecamera;

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
    SurfaceHolder mHolder;
    Camera mCamera;
    public CameraPreview(Context context)
    {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(width, height);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        if(mCamera == null){
            mCamera = Camera.open();
            try{
                mCamera.setPreviewDisplay(holder);
            }
            catch(IOException e){
                mCamera.release();
                mCamera = null;
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
}

■カメラの画像を保存してみる

上述のコードを改造して楽しむことにする。

AndroidManifest.xml

以下の記述をManifestファイルに記述してSDカードにアクセスできるようにする。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

MainActivity.java

onTouchEventが実装されたのと、カメラのインスタンスをMainActivityクラスでも使用する点が変更点である。

package jp.info.justoneplanet.android.usecamera;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {
    private CameraPreview mCameraPreview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        mCameraPreview = new CameraPreview(this);
        setContentView(mCameraPreview);
    }

    private static final File OUTPUT_FILE = new File("/sdcard/usecamera.jpg");
    @Override
    public boolean onTouchEvent(MotionEvent event){
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            Camera mCamera = mCameraPreview.getCamera();
            mCamera.takePicture(
                    new ShutterCallback(){
                        @Override
                        public void onShutter()
                        {
                        }
                    },
                    new PictureCallback(){
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera)
                        {
                        }
                    },
                    new PictureCallback(){
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera)
                        {
                            FileOutputStream out = null;
                            try{
                                out = new FileOutputStream(OUTPUT_FILE);
                                out.write(data);
                                out.flush();
                                out.close();
                            }
                            catch(FileNotFoundException e){
                                e.printStackTrace();
                            }
                            catch(IOException e){
                                e.printStackTrace();
                            }
                        }
                    }
            );
        }
        return false;
    }
}

CameraPreview.java

MainActivityクラスでCameraのインスタンスを使用するために、getterメソッドを追記した。それ以外は何も変わっていない。

package jp.info.justoneplanet.android.usecamera;

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
    SurfaceHolder mHolder;
    Camera mCamera;
    public CameraPreview(Context context)
    {
        super(context);
        
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(width, height);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        if(mCamera == null){
            mCamera = Camera.open();
            
            try{
                mCamera.setPreviewDisplay(holder);
            }
            catch(IOException e){
                mCamera.release();
                mCamera = null;
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
    
    public Camera getCamera(){
        return mCamera;
    }
}

やっぱandroidを触るのって楽しい((o(^-^)o))ワクワク

4 Comments»

とても参考になりました.

実機でのテストも出来ました.

でも,実機からでは保存された画像を見ることができません.
見る方法はありますか?

また,保存先をSDカード内の任意のフォルダにするにはどうしたらいいですか?

初心者で,すみません.

>実機からでは保存された画像を見ることができません.見る方法はありますか?
実際に表示する部分のコードを書いてなかったですね…

画像の表示に関しては以下のコードがシンプルで参考になるかと思います
http://www.hp3200.com/android-app-development/a-image.html

但し以下のメソッドはリソースファイルからの読み込みなので

BitmapFactory.decodeResource

以下のように変更する必要があるかと思います。

BitmapFactory.decodeFile(pathName);

保存先についてはOUTPUT_FILEを変更すれば大丈夫かと思います。

迅速に答えて頂きありがとうございました.

試してみます.

ありがとうございます。
とても参考になりました。

RSS feed for comments on this post.TrackBack URL

Leave a comment