File "CameraView.java"
Path: /WAF - Wireless Android Framework/WAF_0.1_Android/src/rfo/mougino/waf/CameraView.java
File size: 12.38 KB
MIME-type: text/plain
Charset: utf-8
/****************************************************************************************************
BASIC! is an implementation of the Basic programming language for
Android devices.
Copyright (C) 2010 - 2014 Paul Laughton
This file is part of BASIC! for Android
BASIC! is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
BASIC! is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with BASIC!. If not, see <http://www.gnu.org/licenses/>.
You may contact the author or current maintainers at http://rfobasic.freeforums.org
Some of the code in this module is based upon code obtained from:
http://www.brighthub.com/mobile/google-android/articles/43414.aspx
*************************************************************************************************/
package rfo.mougino.waf;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
// **************************** Using the device camera UI ******************************
public class CameraView extends Activity implements SurfaceHolder.Callback,
OnClickListener{
public static final int PICTURE_MODE_USE_UI = 0;
public static final int PICTURE_MODE_AUTO = 1;
public static final int PICTURE_MODE_MANUAL = 2;
public static final int PICTURE_MODE_BLIND = 3; // preview on dummy surface, view is black, implies PICTURE_MODE_AUTO
public static final String EXTRA_PICTURE_MODE = "picture_mode";
public static final String EXTRA_CAMERA_NUMBER = "camera_number";
public static final String EXTRA_FLASH_MODE = "flash_mode";
public static final String EXTRA_FOCUS_MODE = "focus_mode";
private int mPictureMode;
private int mCameraNumber;
private int mNewFlashMode;
private int mNewFocusMode;
private boolean mAutoFocus;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Intent intent = getIntent();
mPictureMode = intent.getIntExtra(EXTRA_PICTURE_MODE, 0);
mCameraNumber = intent.getIntExtra(EXTRA_CAMERA_NUMBER, 0);
mNewFlashMode = intent.getIntExtra(EXTRA_FLASH_MODE, 0);
mNewFocusMode = intent.getIntExtra(EXTRA_FOCUS_MODE, 0);
if (mPictureMode == PICTURE_MODE_USE_UI) {
doCameraUI();
} else {
doCameraNow();
}
}
private void doCameraUI(){
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(getTempFileName())) );
startActivityForResult(intent, 254);
}
private String getTempFileName() { return getTempFileName("png"); }
private String getTempFileName(String ext){ // ext is "png" or "jpg"
return Basic.getDataPath("image." + ext);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((resultCode == RESULT_OK) && (requestCode == 254)) {
String fn = getTempFileName();
try {
BitmapFactory.Options BFO = new BitmapFactory.Options();
BFO.inSampleSize = 4;
Run.CameraBitmap = BitmapFactory.decodeFile(fn, BFO); // Make the bit map from the file
}
catch (Exception e) {}
}
Run.CameraDone = true;
finish();
}
protected void onDestroy() {
Run.CameraDone = true;
if (mPreviewRunning || mAutoFocus || (mCamera != null)) {
surfaceDestroyed(null);
}
super.onDestroy();
}
// **************************** Auto/Manual shutter, No UI **********************************
private static final String TAG = "CameraTest";
private Camera mCamera = null;
boolean mPreviewRunning = false;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private void doCameraNow() {
if (mPictureMode != PICTURE_MODE_BLIND) {
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.camera);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
} else {
mSurfaceView = new SurfaceView(getApplicationContext());
}
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
switch (mPictureMode) {
case PICTURE_MODE_MANUAL:
mSurfaceView.setOnClickListener(this);
/** FALL THROUGH to add callback **/
case PICTURE_MODE_AUTO:
mSurfaceHolder.addCallback(this);
break;
case PICTURE_MODE_BLIND:
surfaceCreated(mSurfaceHolder);
surfaceChanged(mSurfaceHolder, 0, 0, 0);
break;
default:
Log.e(TAG, "Invalid picture mode " + mPictureMode);
break;
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Camera.ErrorCallback errorCallback = new Camera.ErrorCallback() {
public void onError(int error, Camera camera) {
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
// The callback is not currently being called
public void onPictureTaken(byte[] imageData, Camera c) {
if (imageData != null) {
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 0;
Run.CameraBitmap = BitmapFactory.decodeByteArray(imageData, 0,
imageData.length,options);
Run.CameraDone = true;
System.gc();
finish();
}
}
};
Camera.AutoFocusCallback focusCallback = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
try{
mCamera.takePicture(null, null, null, pngCallback);
} catch (Exception e){
Log.e(TAG, "Camera Exception " + e);
}
}
};
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
// The callback is not currently being called
public void onPictureTaken(byte[] data, Camera camera) {
savePicture("jpg", data);
}
};
Camera.PictureCallback pngCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
savePicture("png", data);
}
};
private void savePicture(String ext, byte[] data) {
FileOutputStream outStream = null;
String fn = getTempFileName(ext);
try {
outStream = new FileOutputStream(fn);
outStream.write(data);
outStream.close();
// Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (Exception e) {
}
System.gc();
BitmapFactory.Options BFO = new BitmapFactory.Options();
BFO.inSampleSize = 4;
Run.CameraBitmap = BitmapFactory.decodeFile(fn,BFO); // Make the bit map from the file
// if (Run.CameraManual) mCamera.startPreview();
Run.CameraDone = true;
finish();
}
public void surfaceCreated(SurfaceHolder holder) {
// Log.d(TAG, "surfaceCreated");
try { // Run has previously determined SDK Level
if (mCameraNumber == -1 ) { mCamera = Camera.open(); } // If number = -1 then use level < 9 command
else { mCamera = Camera.open(mCameraNumber); } // else use level >= 9 command
}
catch (Exception e){ // If open fails, we are done.
Log.e(TAG, "Camera open error: " + e);
mCamera = null;
}
if (mCamera != null) {
if (!setParameters()) {
mCamera = null;
} else try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mPreviewRunning = true;
} catch (Exception e) {
Log.e(TAG, "Camera start preview error : " + e);
try {
mCamera.stopPreview();
} catch (Exception e1) {
// ignore: the preview didn't get started
} finally {
mCamera = null;
}
}
}
if (mCamera == null) {
Run.CameraDone = true;
finish();
}
}
public void onClick(View arg0) {
if (mPictureMode == PICTURE_MODE_MANUAL) {
if (!mAutoFocus) {
try {
mCamera.takePicture(null, null, null, pngCallback);
} catch (Exception e) {
Log.e(TAG, "CameraManual Exception " + e);
}
} else {
mCamera.autoFocus(focusCallback);
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Log.d(TAG, "surfaceChanged");
if (mCamera == null) { // If no camera link then done
Log.e(TAG, "Surface changed. mCamera NULL ");
Run.CameraDone = true;
finish();
return;
}
// If Auto shutter, take picture now.
if (mPictureMode == PICTURE_MODE_AUTO || mPictureMode == PICTURE_MODE_BLIND) {
if (!mAutoFocus) {
try{
mCamera.takePicture(null, null, null, pngCallback);
} catch (Exception e){
Log.e(TAG, "CameraAuto Exception " + e);
}
} else {
mCamera.autoFocus(focusCallback);
}
}
}
private boolean setParameters() {
Camera.Parameters p = mCamera.getParameters();
String oldMode = p.getFlashMode();
String newMode;
switch (mNewFlashMode) {
case 0: newMode = Camera.Parameters.FLASH_MODE_AUTO; break;
case 1: newMode = Camera.Parameters.FLASH_MODE_ON; break;
case 2: newMode = Camera.Parameters.FLASH_MODE_OFF; break;
case 3: newMode = Camera.Parameters.FLASH_MODE_TORCH; break; //Full Power/Flashlight/2013-07-25-16-42 gt
case 4: newMode = Camera.Parameters.FLASH_MODE_RED_EYE; break; //Flashlight/2013-07-27-19-12 gt
default: newMode = ""; break;
}
List<String> supportedModes = p.getSupportedFlashModes();
if ((oldMode != null) && (supportedModes != null)) {
for (String mode : supportedModes) {
if (mode.equals(newMode)) {
p.setFlashMode(newMode);
break;
}
}
} else { // "Supported Modes" not supported!
p.setFlashMode(newMode); // Just do it. May not work, but doesn't seem to hurt.
}
oldMode = p.getFocusMode();
switch (mNewFocusMode) { //Focus/2013-07-25-17-37 gt
case 0: newMode = Camera.Parameters.FOCUS_MODE_AUTO; break;
case 1: newMode = Camera.Parameters.FOCUS_MODE_FIXED; break;
case 2: newMode = Camera.Parameters.FOCUS_MODE_INFINITY; break;
case 3: newMode = Camera.Parameters.FOCUS_MODE_MACRO; break;
// (4 CONTINUOUS_VIDEO permissions?)
//case 5: newMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO; break;
default: newMode = ""; break;
}
supportedModes = p.getSupportedFocusModes();
if ((oldMode != null) && (supportedModes != null)) {
for (String mode : supportedModes) {
if (mode.equals(newMode)) {
p.setFocusMode(newMode);
mAutoFocus = mode.equals(Camera.Parameters.FOCUS_MODE_AUTO);
break;
}
}
} else { // "Supported Modes" not supported!
p.setFlashMode(newMode); // Just do it. May not work, but doesn't seem to hurt.
}
// if (Run.CameraSceneModeBarcode == 1) p.setSceneMode(Camera.Parameters.SCENE_MODE_BARCODE);
// Use the largest preview size
List<Camera.Size> sizes = p.getSupportedPreviewSizes();
Camera.Size cs = sizes.get(0);
for (Camera.Size ps : sizes) { //2013-07-27-01-15 gt
if (cs.width < ps.width) {
cs = ps;
}
}
p.setPreviewSize(cs.width, cs.height);
// Use the largest picture size
sizes = p.getSupportedPictureSizes();
cs = sizes.get(0);
for (Camera.Size ps : sizes) { //2013-07-27-01-15 gt
if (cs.width < ps.width) {
cs = ps;
}
}
p.setPictureSize(cs.width, cs.height);
// Now set the parameters
try {
mCamera.setParameters(p);
} catch (Exception e) {
Log.e(TAG, "Camera parameter set error : " + e);
Run.CameraDone = true;
finish();
return false;
}
return true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Log.d(TAG, "surfaceDestroyed");
if (mPreviewRunning) {
if (mCamera != null) { mCamera.stopPreview(); }
mPreviewRunning = false;
}
if (mAutoFocus) {
if (mCamera != null) {mCamera.cancelAutoFocus(); }
mAutoFocus = false;
}
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}