凄く基本的なコード。別にすごいことはしてない。備忘録程度。
■カメラを起動する
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))ワクワク
とても参考になりました.
実機でのテストも出来ました.
でも,実機からでは保存された画像を見ることができません.
見る方法はありますか?
また,保存先をSDカード内の任意のフォルダにするにはどうしたらいいですか?
初心者で,すみません.
>実機からでは保存された画像を見ることができません.見る方法はありますか?
実際に表示する部分のコードを書いてなかったですね…
画像の表示に関しては以下のコードがシンプルで参考になるかと思います
http://www.hp3200.com/android-app-development/a-image.html
但し以下のメソッドはリソースファイルからの読み込みなので
以下のように変更する必要があるかと思います。
保存先についてはOUTPUT_FILEを変更すれば大丈夫かと思います。
迅速に答えて頂きありがとうございました.
試してみます.
ありがとうございます。
とても参考になりました。