本⽇日の講義内容
1. カメラの利⽤用
1.
カメラ利⽤用の基礎
2.
プレビュー画⾯面表⽰示サンプル
2. 撮影処理と保存
1.
撮影時のCallback利⽤用
2.
撮影処理シーケンス
3.
写真撮影サンプルプログラム
3. オートフォーカスによる撮影
1.
オートフォーカス機能の解説
2.
オートフォーカスに必要な記述
3.
オートフォーカス機能を利⽤用した
サンプルプログラム
4. 撮影モードの変更
1.
撮影モードの紹介
2.
撮影モード変更の⽅方法
3.
撮影モードを変更した場合のサン
プルプログラム
第 1 章
カメラの利⽤用
•
カメラを利⽤用する事前準備
–
カメラを使⽤用するためには,SDカードの利⽤用と同様「AndroidManifest.xml」にパー
ミッションの設定を追加する必要があります.
–
カメラを使⽤用するためのパーミッションとして以下を追加します.
– <uses-permission android:name="android.permission.CAMERA" />–
また,通常のカメラアプリは,端末を横向きにして利⽤用するため,アプリ画⾯面を横向
き利⽤用に固定するため,Activityの属性を以下に変更します
–
<ac$vity android:name=”.CameraPreviewAc$vity"
–
android:label="@string/app_name"
–
android:screenOrienta$on="landscape">
•
Androidプロジェクトの⽣生成
–
新規Androidプロジェクトを下記の設定値で作成.
項⽬目名 設定値 プロジェクト名 Sample5 ビルドターゲット Android 2.2にチェックを付ける アプリケーション名 Sample15 パッケージ名 Jp.ac.uot.sample15 Create Activity CameraPreviewActivityカメラの利⽤用
•
全画⾯面プレビュー表⽰示のために
–
カメラアプリにおいて,撮影時のプレビュー画⾯面は⼤大きい⽅方が望ましい,そこで,今
回のサンプルコードでは,画⾯面全体をプレビュー表⽰示に⽤用いてみたいと思う.
–
全画⾯面をViewに利⽤用するためには,以下の記述をonCreateメソッドないで定義する
必要がある.
–
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
–
これにより,アプリケーションの画⾯面に対して,全画⾯面表⽰示を⾏行行うというフラグを設
定することができる.
•
タイトルバーの削除のために
–
せっかくプレビュー画⾯面を全画⾯面表⽰示させているのにもかかわらず,タイトルバーが
上部に残っているのはみっともないので,今回のサンプルコードでは,タイトルバー
を削除する設定を⾏行行いたいと思う.
–
アプリ画⾯面からタイトルバーを削除するためには,以下の記述をonCreateメソッド
ないで定義する必要がある.
–
requestWindowFeature(Window.FEATURE_NO_TITLE);
–
これにより,アプリケーションの画⾯面から,タイトルバーを削除することがをできる.
•
プレビュー画⾯面表⽰示⽤用のViewクラス作成
–
プレビュー画⾯面を表⽰示するためにmain.xmlではなく,⾃自分でViewクラスを継承した
クラスを作成する必要がある.
–
サンプルでは,SurfaceViewクラスを継承したCameraPreview.javaというクラスを
作成している.同じパッケージ内にJavaクラスの新規作成で上記ファイルを⽣生成.
カメラの利⽤用
•
CameraPreviewActivity.javaの編集
package jp.ac.uot.sample15; import android.app.Ac8vity; import android.os.Bundle;
public class CameraPreviewAc8vity extends Ac8vity { /** Called when the ac.vity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
CameraPreview view = new CameraPreview(this); setContentView(view);
}
@Override
protected void onResume(){ super.onResume();
}
@Override
protected void onStop(){ super.onStop();
}
@Override
public void onDestroy(){ super.onDestroy(); }
カメラの利⽤用
•
CameraPreview.javaの編集
package jp.ac.uot.sample15; import android.content.Context; import android.hardware.Camera; import android.view.SurfaceHolder; import android.view.SurfaceView;public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{ private Camera camera;
public CameraPreview(Context context) { super(context);
// TODO Auto-‐generated constructor stub getHolder().addCallback(this);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-‐generated method stub
Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(width, height);
camera.setParameters(parameters); camera.startPreview();
カメラの利⽤用
•
CameraPreview.javaの編集
@Override
public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera = Camera.open(); try {
camera.setPreviewDisplay(holder); } catch (Excep8on e) {
e.printStackTrace(); }
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera.release(); camera = null; }
カメラの利⽤用
•
AndroidManifest.xml の編集
<?xml version="1.0" encoding="u@-‐8"?> <manifest xmlns:android="hFp://schemas.android.com/apk/res/android" package="jp.ac.uot.sample15" android:versionCode="1" android:versionName="1.0" > <uses-‐sdk android:minSdkVersion="8" /> <uses-‐permission android:name="android.permission.CAMERA"/> <applica.on android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <ac.vity android:name=".CameraPreviewAcWvity" android:label="@string/app_name" > <intent-‐filter> <ac.on android:name="android.intent.acWon.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-‐filter> </ac.vity> </applica.on> </manifest>カメラの利⽤用
第 3 章
撮影と保存処理
•
撮影処理
–
プレビュー画⾯面にカメラからの映像が表⽰示できたので,今度は画像を撮影して保存し
てみたいと思う.
–
プレビュー画像を取得する為には,CameraPreview.java内で作成したCamera型の
オブジェクトに対して,
–
camera.takePicture()
–
を実⾏行行することで,キャプチャを取得.
•
Androidプロジェクトの⽣生成
–
新規Androidプロジェクトを下記の設定値で作成.
項⽬目名 設定値 プロジェクト名 Sample16 ビルドターゲット Android 2.2にチェックを付ける アプリケーション名 Sample16 パッケージ名 jp.ac.uot.sample16 Create Activity PhotoShootActivity•
画⾯面へのタッチイベント処理
–
⼀一般のカメラアプリ同様,タッチしたときに撮影処理を実⾏行行したいので,タッチイベ
ントの取得を⾏行行う.
撮影と保存処理
•
takePictureメソッドのコールバック
–
3つのデータを引数でcallback関数をいれることができる.
–
1つ⽬目:シャッターを切った時
–
2つ⽬目:rowデータを取得した時
–
3つ⽬目:jpegに圧縮した時
–
で実⾏行行される.
–
rawデータは⼗十分な要領がなければコピーできないので,nullかもしれないという罠
もある.
–
そのため,3つ⽬目の関数で画像の保存処理を実⾏行行する.
•
画像保存の処理
–
この関数ないで処理をする.
–
最初にdataがnullでないことを確認した後に,SDカードへの保存と同じ要領で処理を
記述する.最後にAndroidのデータベースに画像を登録してギャラリーに表⽰示させる.
private Camera.PictureCallback mPictureListener =new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) {
} };
ContentValues values = new ContentValues();
ContentResolver contentResolver = context.getContentResolver(); values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put("_data", imgName);
撮影と保存処理
•
PhotoShootActivity.javaの編集
package ac.jp.uot.sample16; import android.app.Ac.vity; import android.os.Bundle;
public class PhotoShootAc.vity extends Ac.vity { /** Called when the ac.vity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
CameraPreview view = new CameraPreview(this); setContentView(view);
}
@Override
protected void onResume(){
super.onResume();
}
@Override
protected void onStop(){
super.onStop();
}
@Override
public void onDestroy(){
super.onDestroy();
} }
撮影と保存処理
•
CameraPreview.javaの編集
package ac.jp.uot.sample16; import java.io.File; import java.io.FileOutputStream; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.hardware.Camera; import android.os.Environment; import android.provider.MediaStore; import android.provider.MediaStore.Images; import android.view.Mo8onEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.Toast;public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{ private Camera camera;
private Boolean bool = true; private Context context;
public CameraPreview(Context context) { super(context);
// TODO Auto-‐generated constructor stub this.context = context;
getHolder().addCallback(this);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }
撮影と保存処理
•
CameraPreview.javaの編集
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-‐generated method stub
Camera.Parameters parameters = camera.getParameters(); camera.setParameters(parameters);
camera.startPreview(); }
@Override
public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera = Camera.open(); try {
camera.setPreviewDisplay(holder); } catch (Excep8on e) {
e.printStackTrace(); }
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera.release(); camera = null; }
@Override
public boolean onTouchEvent(Mo8onEvent event) { if (event.getAc8on() == Mo8onEvent.ACTION_DOWN) { if (camera != null && bool) {
bool = false;
camera.takePicture(shuferListener, null, jpegListener); }
}
撮影と保存処理
•
CameraPreview.javaの編集
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-‐generated method stub
Camera.Parameters parameters = camera.getParameters(); camera.setParameters(parameters);
camera.startPreview(); }
@Override
public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera = Camera.open(); try {
camera.setPreviewDisplay(holder); } catch (Excep8on e) {
e.printStackTrace(); }
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-‐generated method stub
camera.release(); camera = null; }
撮影と保存処理
•
CameraPreview.javaの編集
@Override
public boolean onTouchEvent(Mo8onEvent event) { if (event.getAc8on() == Mo8onEvent.ACTION_DOWN) { if (camera != null && bool) {
bool = false;
camera.takePicture(shuferListener, null, jpegListener); }
}
return true; }
private Camera.ShuXerCallback shuXerListener = new Camera.ShuXerCallback() { public void onShuXer() {
// TODO Auto-‐generated method stub }
撮影と保存処理
•
CameraPreview.javaの編集
private Camera.PictureCallback jpegListener =new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
if(!sdcardWriteReady()){
Toast.makeText(context, "SDCARDが認識されません。", Toast.LENGTH_SHORT).show(); bool = true;
camera.startPreview(); return;
}
FileOutputStream fos = null;
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/cmr/"); if(!file.exists()){
file.mkdir(); }
String imgName = Environment.getExternalStorageDirectory().getPath() + "/cmr/" + System.currentTimeMillis() +".jpg"; try {
fos = new FileOutputStream(imgName); fos.write(data);
fos.close();
ContentValues values = new ContentValues();
ContentResolver contentResolver = context.getContentResolver(); values.put(Images.Media.MIME_TYPE, "image/jpeg");
撮影と保存処理
•
CameraPreview.javaの編集
try { contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); }catch(Excep8on e){ Toast.makeText(context, "再起動後に画像が認識されます。", Toast.LENGTH_SHORT).show(); e.printStackTrace(); }} catch (Excep8on e) {
Toast.makeText(context, "ファイルの保存中にエラーが発生しました。", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } bool = true; camera.startPreview(); }else{ Toast.makeText(context, "データが取得できませんでした。", Toast.LENGTH_SHORT).show(); bool = true; camera.startPreview(); } } };
private boolean sdcardWriteReady(){
String state = Environment.getExternalStorageState(); return (Environment.MEDIA_MOUNTED.equals(state)); }
第 3 章
オートフォーカスによる撮影
•
Androidプロジェクトの⽣生成
–
新規Androidプロジェクトを下記の設定値で作成.
項⽬目名 設定値 プロジェクト名 Sample17 ビルドターゲット Android 2.2にチェックを付ける アプリケーション名 Sample17 パッケージ名 Jp.ac.uot.sample17 Create Activity AutoFocusActivity•
撮影の仕様
–
Cameraクラスには「autoFocus」というメソッドが存在し,AutoFocusCallbackを
設定しておくことで,オートフォーカスが⾏行行われた直後にコールバックをしてくれま
す.
–
写真撮影にオートフォーカスは必須ではないのですが,オートフォーカス機能を利⽤用
していないとピントの合っていないぼやけた写真が撮影されてしまうため,今回は
オートフォーカス機能を使⽤用した写真を撮影を実装していきます.
–
オートフォーカスを使⽤用した場合,0.5 1秒程度のタイムラグが発⽣生するため瞬時に
撮影したい場合は,オートフォーカスを使⽤用しないという実装も考えられます.
•
AutoFocusActivity.javaの編集
package jp.ac.uot.sample17;
import android.app.Ac8vity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
public class AutoFocus extends Ac8vity {
private sta8c final int MENU_AUTOFOCUS = Menu.FIRST + 1;
private AutoFocusPreview view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
view = new AutoFocusPreview(this);
setContentView(view);
}
•
AutoFocus.javaの編集
@Override
public boolean onCreateOp8onsMenu(Menu menu) {
menu.add(Menu.NONE, MENU_AUTOFOCUS, Menu.NONE, getResources().getString
(R.string.auto_focus));
return super.onCreateOp8onsMenu(menu);
}
@Override
public boolean onPrepareOp8onsMenu(Menu menu) {
return super.onPrepareOp8onsMenu(menu);
}
@Override
public boolean onOp8onsItemSelected(MenuItem item) {
boolean rc = true;
switch (item.getItemId()) {
case MENU_AUTOFOCUS:
view.autoFocus();
break;
default:
rc = super.onOp8onsItemSelected(item);
break;
}
return rc;
}
}
オートフォーカスによる撮影
•
AutoFocusPreview
.javaの編集
package jp.ac.uot.sample17; import java.io.FileOutputStream; import java.io.IOExcep8on; import android.content.Context; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShuXerCallback; import android.u8l.Log; import android.view.Mo8onEvent;public class AutoFocusPreview extends CameraPreview { AutoFocusPreview(Context context) { super(context); } void autoFocus() { camera.autoFocus(new AutoFocusCallback() { @Override
public void onAutoFocus(boolean success, final Camera camera) { ShuXerCallback shuXer = new ShuXerCallback() {
@Override
public void onShuXer() {
Log.d("TEST", "onShuXer");
}
};
PictureCallback raw = new PictureCallback() {
@Override
•
AutoFocusPreview
.javaの編集
PictureCallback raw = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) { Log.d("TEST", "onPictureTaken: raw: data=" + data);
}
};
PictureCallback jpeg = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("TEST", "onPictureTaken: jpeg: data=" + data); FileOutputStream fos = null;
try {
fos = new FileOutputStream("/sdcard/test.jpg");
fos.write(data);
} catch (IOExcep8on e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOExcep8on e) {
e.printStackTrace(); } } } } };
camera.takePicture(shuXer, raw, jpeg);
•
AutoFocusPreview
.javaの編集
camera.takePicture(shuXer, raw, jpeg); new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedExcep8on e) {
} camera.startPreview(); } }.start(); } }); } void cancelAutoFocus() { camera.cancelAutoFocus(); } @Override
public boolean onTouchEvent(Mo8onEvent event) { autoFocus();
return true; }
}