Camera API(カメラ関係の古い方)を使ってみる件
まとめ
- カメラ撮影中の写ってる範囲を表示している部分はプレビューと呼んで
SurfaceView
で扱う - Camera.setParametersでプレビューの時の画像サイズや、プレビュー後(撮影後)の画像サイズが指定できたはずなのだが、compileSDKVersion 25以上で新規プロジェクト作ったらその関数がAndroid Studioから見つからず。。
Camera.getParameters().setPreviewSize()
などだった- PreviewSize(プレビュー中に表示する画像のサイズ)やPictureSize(撮影後にコールバックに渡す画像のサイズ)は機種ごとにサポートしているサイズが決まっているので
- 撮影後、カメラで撮った画像を処理させるには
Camera.PictureCallback
を定義して、Camera.takePicture(ShutterCallback, PictureCallback, PictureCallback)
- ここで2つ目の
PictureCallback
に渡す方のクラスのonPictureTaken(byte[], Camera)
を定義することで撮影した画像の処理を書くことができる Camera.takePicture()
を呼び出すと、プレビュー部分の画像の更新が止まる.Camera.startPreview()
で再びPreview表示を動かすことができる
- ここで2つ目の
android { compileSdkVersion 25 buildToolsVersion "25.0.1" defaultConfig { applicationId "com.example.woshidan.cameratest" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
のとき、Camera APII(カメラ関係の古い方)をちょっと触ってみた。 CameraPreview
はほぼ公式のチュートリアルのまま。
以下のコードでは、一回シャッターボタンを押すと画像がボタンを押したタイミングで止まり、もう一度押すとプレビューが再開される、みたいなもの。
public class MainActivity extends Activity { private Camera mCamera; private CameraPreview mPreview; private boolean isCaptured = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create an instance of Camera mCamera = getCameraInstance(); // mCamera.getParameters().setXXX...でプレビュー画面の設定などのパラメータを設定できる List<Camera.Size> supportedSizes = mCamera.getParameters().getSupportedPreviewSizes(); mCamera.getParameters().setPreviewSize(supportedSizes.get(supportedSizes.size() - 1).width, supportedSizes.get(supportedSizes.size() - 1).height); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); Button captureButton = (Button) findViewById(R.id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // get an image from the camera if (isCaptured) { mCamera.startPreview(); // 撮影用のプレビューをもう一度動かす isCaptured = false; } else { mCamera.takePicture(null, null, mPicture); // 撮影結果を撮影結果をあれこれするコールバック(Camera.PictureCallback)へ渡す // この関数を呼び出すと、Preview部分の表示の更新は止まる isCaptured = true; } } } ); } /** A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(0); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 結果をSDカードに書き込んだりする } };
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.woshidan.cameratest"> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /><!-- カメラが使えない端末でプレイストアで検索したときこのアプリを表示させない --> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@android:style/Theme.Holo"> <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="landscape" android:theme="@android:style/Theme.Holo.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>