
Androidの勉強中です。
カメラから画像を取得して、グレスケ化して表示。
Androidでは、カメラから取得出来るデータはRGBではありません。
YUV420形式のbyte型の配列が帰ってきます。
なので、自分でRGBに変換してやらなければいけません。
ただし、グレースケールの場合は処理が簡単。
取得した配列の先頭から、画像の縦×横分のデータをそのまま取ってきて画像とすればOK。
多分だけど。
正直このあたりまだ曖昧。
カメラを利用したリアルタイム処理については、以下の山添さんの資料がとても参考になりました。
・ワーキンググループ/金沢支部/第四回勉強会 – 日本Androidの会(日本アンドロイドの会)
以下、今回のソースです。
Main.javaのソース。
package jp.sakef;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
public class Main extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 画面の向きを横で固定
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// 全画面表示
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// スリープ無効
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// タイトルの非表示
requestWindowFeature(Window.FEATURE_NO_TITLE);
// レイアウト用
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
// viewの初期化と追加
DrawView dView = new DrawView(this);
CameraView camView = new CameraView(this, dView);
setContentView(dView, layoutParams);
addContentView(camView, layoutParams);
}
}
CameraView.javaのソース。
package jp.sakef;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraView extends SurfaceView implements Camera.PreviewCallback, SurfaceHolder.Callback
{
private Camera camera;
private DrawView view;
private int w=240, h=160;
private float scaleX, scaleY;
private int[] grayScales;
private int[] grayScaleTable;
// コンストラクタ
public CameraView(Context context, DrawView view)
{
super(context);
this.view = view;
// holderの設定
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// viewのフォーカス設定
this.setFocusable(true);
this.requestFocus();
}
// viewに変化があった場合に実行
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
scaleX = width / w;
scaleY = height / h;
grayScales = new int[w*h];
grayScaleTable = new int[256];
for(int i=0 ; i<256 ; i++) grayScaleTable[i] = 0xff000000 + (i<<16) + (i<<8) + i;
try
{
// カメラの設定
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(240 , 160);
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(this);
camera.startPreview();
}
catch (IOException e) {}
}
// viewが作成されたら実効
public void surfaceCreated(SurfaceHolder holder)
{
camera = Camera.open();
}
// viewが破棄されたら実効
public void surfaceDestroyed(SurfaceHolder holder)
{
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
//プレビュー画像の取得
public void onPreviewFrame(byte[] data, Camera camera)
{
camera.setPreviewCallback(null);
int size = w*h;
int pos = 0;
for(int i=0 ; i<size ; i+=8)
{
int y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
y = data[pos]&0xff;
grayScales[pos++] = grayScaleTable[y];
}
view.drawBitmap(grayScales, scaleX, scaleY, w, h);
camera.setPreviewCallback(this);
invalidate();
}
}
DrawView.javaのソース。
package jp.sakef;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class DrawView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private Paint paint;
public DrawView(Context context)
{
super(context);
holder = getHolder();
holder.addCallback(this);
paint = new Paint();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
holder.removeCallback(this);
holder=null;
}
public void drawBitmap(int[] img, float scaleX, float scaleY, int w, int h)
{
Canvas canvas = holder.lockCanvas();
canvas.scale(scaleX, scaleY);
canvas.drawBitmap(img, 0, w, 0, 0, w, h,false, paint);
holder.unlockCanvasAndPost(canvas);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
public void surfaceCreated(SurfaceHolder holder) {}
}