HT-03Aでプレビューの映像データをビットマップデータに変換して保存する方法。
カメラのプレビュー画像を画面に表示するには、SurfaceView を継承したビュークラスを作成して、Activityにセットする。
こんなアクティビティを作成する。以後ソース。
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
public class CameraActivity extends Activity {
private CameraPreview mCameraPreview; // カメラプレビュー
/**
* アクティビティ起動
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// フルスクリーン・タイトルなし・ディスプレイを常に明るく
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// カメラプレビュー
mCameraPreview = new CameraPreview(this);
setContentView(mCameraPreview);
}
/**
* キー操作
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// HT-03Aならトラックボールを押し込んだ
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
mCameraPreview.takePicture(); // 撮影
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
/**
* 復帰
*/
@Override
public void onResume() {
super.onResume();
// カメラ復帰処理
mCameraPreview.onResume();
}
/**
* 退避
*/
@Override
public void onPause() {
super.onPause();
// カメラ退避処理
mCameraPreview.onPuse();
}
}
つづいてカメラプレビュー
// import 略
public class CameraPreview extends SurfaceView
implements SurfaceHolder.Callback {
private SurfaceHolder mHolder; // サーフェースホルダー
private Context mContext; // コンテクスト
private Camera mCamera; // カメラ
private Camera.Parameters mCamparam; // カメラ設定
private boolean mProgress; // 撮影実行中フラグ
private boolean mHasSurface; // サーフェースの存在フラグ
private boolean mCameraPreviewing; // プレビュー実行フラグ
private Bitmap mBitmap; // 撮影されたビットマップ
/**
* コンストラクタ
* @param context
*/
public CameraPreview(Context context) {
super(context);
mContext = context;
mHolder = getHolder();
initSurface();
}
/**
* サーフェース作成後のコールバック
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamparam = mCamera.getParameters();
mCamparam.setPreviewSize(width, height);
mCamera.setParameters(mCamparam);
startCameraPreview();
}
/**
* 画面の作成コールバッック
*/
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamparam = mCamera.getParameters();
try {
mCamera.setPreviewDisplay(holder);
} catch(Exception e) {
mCamera.release();
mCamera = null;
}
mHasSurface = true;
}
/**
* 画面の破棄コールバック
*/
public void surfaceDestroyed(SurfaceHolder holder) {
cameraDestroy();
mHasSurface = false;
}
/**
* 再開
*/
public void onResume() {
if (mHasSurface) {
surfaceCreated(mHolder);
startCameraPreview();
} else {
initSurface();
}
}
/**
* 一時停止
*/
public void onPuse() {
cameraDestroy();
}
/**
* サーフェースの初期化
*/
private void initSurface() {
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* プレビューの開始
*/
private void startCameraPreview() {
if (!mCameraPreviewing) {
mCamera.startPreview();
mCameraPreviewing = true;
}
}
/**
* プレビューの停止
*/
private void stopCameraPreview() {
if (mCameraPreviewing) {
mCamera.stopPreview();
mCameraPreviewing = false;
}
}
/**
* カメラの開放
*/
private void cameraDestroy() {
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
}
/**
* 撮影コマンド
*/
public void takePicture() {
if (!mProgress) {
mProgress = true;
mCamera.setPreviewCallback(savePreviewImage); // ここでプレビューコールバックをセット
}
}
/**
* プレビューコールバック
* prepareSavePreviewImageコールバックで登録され、プレビュー画像を取得する
*/
private final Camera.PreviewCallback savePreviewImage =
new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
mCamera.setPreviewCallback(null); // ここですぐにプレビューコールバックを解除
stopCameraPreview();
mProgress = true;
saveImage(data); // 画像の保存
startCameraPreview();
}
};
/**
* カメラのプレビューデータを保存する
*
*/
private boolean saveImage(byte[] data) {
if (data == null) {
return false;
}
final int width = getWidth();
final int height = getHeight();
// 変換後のピクセル配列
int[] rgb = new int[(width * height)];
try {
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// YUV420からBitmapに変換
decodeYUV420SP(rgb, data, width, height);
mBitmap.setPixels(rgb, 0, width, 0, 0, width, height);
} catch (Exception e) {
return false;
}
// 取得できたBitmapインスタンスをファイルに保存するところ略
return true;
}
/**
* YUV420データをBitmapに変換する
* @param rgb
* @param yuv420sp
* @param width
* @param height
*/
// YUV420 to BMP
public static final void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
}
これでHT-03Aでトラックボールを押し込んだときにプレビューデータをビットマップ型に変更できる。・・・はず。
あとは保存するなり送信するなり。
Related posts:
関連記事はYARPP関連記事プラグインによって表示されています。

