2011年9月22日木曜日

AndroidのカメラプレビューでOverlayを表示する方法

このエントリーをはてなブックマークに追加

【構成】

【MainActivity.java - メインアクティビティー】

package com.ayakix;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
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().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new CameraView(this));
addContentView(new CameraOverlayView(this), new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
}


【CameraView.java - カメラサーフェースビュー】

package com.ayakix;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PictureCallback, Camera.AutoFocusCallback {
private SurfaceHolder holder;
private Camera camera;

public CameraView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
camera.setPreviewDisplay(holder);
} catch (Exception e) {
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
camera.startPreview();
}

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

@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
camera.autoFocus(this);
}
return true;
}

@Override
public void onAutoFocus(boolean success, Camera camera) {
camera.autoFocus(null);
camera.takePicture(null, null, this);
}

@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
// bitmap画像をカットする処理など
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// 中央部分の四角形をカット
bitmap = cutBitmap(bitmap, (w-h)/2, 0, h, h);
// 90度回転
bitmap = rotateBitmap90(bitmap);

// とりあえずもう一度カメラプレビュー
camera.startPreview();
} catch (Exception e) {
}
}

/*
* カット
*/
public Bitmap cutBitmap(Bitmap bmp,int x,int y,int w,int h) {
Bitmap result=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(result);
canvas.drawBitmap(bmp,-x,-y,null);
return result;
}
/*
* 画像の回転 90度
*/
public Bitmap rotateBitmap90(Bitmap bmp) {
int w=bmp.getWidth();
int h=bmp.getHeight();
Bitmap result=Bitmap.createBitmap(h,w,Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(result);
canvas.rotate(90,0,0);
canvas.drawBitmap(bmp,0,-h,null);
return result;
}
}


【CameraOverlayView.java - オーバーレイビュー】

package com.ayakix;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class CameraOverlayView extends View {
private int width, height;

public CameraOverlayView(Context context) {
super(context);
setFocusable(true);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
// ビューのサイズを取得
width= w;
height= h;
}


/**
* 描画処理
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 背景色を設定
canvas.drawColor(Color.TRANSPARENT);

// 描画するための線の色を設定
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setARGB(100, 0, 0, 0);

// 上枠表示
canvas.drawRect(0, 0, (width-height)/2, height, paint);
// 下枠表示
canvas.drawRect((width-height)/2 + height, 0, width, height, paint);

// 中央十字憑依時
int len = height / 10;
paint.setARGB(255, 255, 0, 0);
canvas.drawLine(width/2, height/2-len, width/2, height/2+len, paint);
canvas.drawLine(width/2-len, height/2, width/2+len, height/2, paint);
// 円表示
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(width/2, height/2, len*5, paint);
}
}


【AndroidManifest.xml】

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ayakix"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />

<uses-permission android:name="android.permission.CAMERA" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activity.CameraActivity" android:screenOrientation="landscape"></activity>

</application>
</manifest>